wined3d: Add support for GLSL based fixed function vertex shaders.
[wine/multimedia.git] / dlls / wined3d / state.c
blobeddff66cc04e4cc1244610c7db336b236288a8a8
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 static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
587 context->load_constants = 1;
590 void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
592 const struct wined3d_gl_info *gl_info = context->gl_info;
593 DWORD enable = 0xffffffff;
594 DWORD disable = 0x00000000;
596 if (use_vs(state))
598 if (!context->d3d_info->vs_clipping)
600 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
601 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
602 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
603 * of that - don't do anything here and keep them disabled
605 if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
607 static BOOL warned = FALSE;
608 if(!warned) {
609 FIXME("Clipping not supported with vertex shaders\n");
610 warned = TRUE;
613 return;
616 /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
617 * hardcoded into the shader. Update the shader to update the enabled clipplanes */
618 context->select_shader = 1;
619 context->load_constants = 1;
622 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
623 * of already set values
626 /* If enabling / disabling all
627 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
629 if (state->render_states[WINED3D_RS_CLIPPING])
631 enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
632 disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
634 else
636 disable = 0xffffffff;
637 enable = 0x00;
640 if (enable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE0);
641 if (enable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE1);
642 if (enable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE2);
643 if (enable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE3);
644 if (enable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE4);
645 if (enable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE5);
646 checkGLcall("clip plane enable");
648 if (disable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0);
649 if (disable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1);
650 if (disable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2);
651 if (disable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3);
652 if (disable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4);
653 if (disable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5);
654 checkGLcall("clip plane disable");
657 void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
659 const struct wined3d_gl_info *gl_info = context->gl_info;
660 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
661 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
662 * specular color. This is wrong:
663 * Separate specular color means the specular colour is maintained separately, whereas
664 * single color means it is merged in. However in both cases they are being used to
665 * some extent.
666 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
667 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
668 * running 1.4 yet!
671 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
672 * Instead, we need to setup the FinalCombiner properly.
674 * The default setup for the FinalCombiner is:
676 * <variable> <input> <mapping> <usage>
677 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
678 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
679 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
680 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
681 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
682 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
683 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
685 * That's pretty much fine as it is, except for variable B, which needs to take
686 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
687 * whether WINED3D_RS_SPECULARENABLE is enabled or not.
690 TRACE("Setting specular enable state and materials\n");
691 if (state->render_states[WINED3D_RS_SPECULARENABLE])
693 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
694 checkGLcall("glMaterialfv");
696 if (state->material.power > gl_info->limits.shininess)
698 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
699 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
700 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
701 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
702 * them, it should be safe to do so without major visual distortions.
704 WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
705 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
707 else
709 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
711 checkGLcall("glMaterialf(GL_SHININESS)");
713 if (gl_info->supported[EXT_SECONDARY_COLOR])
714 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_SUM_EXT);
715 else
716 TRACE("Specular colors cannot be enabled in this version of opengl\n");
717 checkGLcall("glEnable(GL_COLOR_SUM)");
719 if (gl_info->supported[NV_REGISTER_COMBINERS])
721 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
722 checkGLcall("glFinalCombinerInputNV()");
724 } else {
725 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
727 /* for the case of enabled lighting: */
728 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
729 checkGLcall("glMaterialfv");
731 /* for the case of disabled lighting: */
732 if (gl_info->supported[EXT_SECONDARY_COLOR])
733 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
734 else
735 TRACE("Specular colors cannot be disabled in this version of opengl\n");
736 checkGLcall("glDisable(GL_COLOR_SUM)");
738 if (gl_info->supported[NV_REGISTER_COMBINERS])
740 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
741 checkGLcall("glFinalCombinerInputNV()");
745 TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
746 state->material.diffuse.r, state->material.diffuse.g,
747 state->material.diffuse.b, state->material.diffuse.a);
748 TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
749 state->material.ambient.r, state->material.ambient.g,
750 state->material.ambient.b, state->material.ambient.a);
751 TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
752 state->material.specular.r, state->material.specular.g,
753 state->material.specular.b, state->material.specular.a);
754 TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
755 state->material.emissive.r, state->material.emissive.g,
756 state->material.emissive.b, state->material.emissive.a);
758 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
759 checkGLcall("glMaterialfv(GL_AMBIENT)");
760 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
761 checkGLcall("glMaterialfv(GL_DIFFUSE)");
762 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
763 checkGLcall("glMaterialfv(GL_EMISSION)");
766 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
768 const struct wined3d_gl_info *gl_info = context->gl_info;
769 unsigned int i;
771 /* Note the texture color applies to all textures whereas
772 * GL_TEXTURE_ENV_COLOR applies to active only. */
773 float col[4];
774 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
776 /* And now the default texture color as well */
777 for (i = 0; i < context->d3d_info->limits.ffp_blend_stages; ++i)
779 /* Note the WINED3D_RS value applies to all textures, but GL has one
780 * per texture, so apply it now ready to be used! */
781 context_active_texture(context, gl_info, i);
783 gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
784 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
788 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
789 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
791 const struct wined3d_gl_info *gl_info = context->gl_info;
793 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
794 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
795 GL_EXTCALL(glActiveStencilFaceEXT(face));
796 checkGLcall("glActiveStencilFaceEXT(...)");
797 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
798 checkGLcall("glStencilFunc(...)");
799 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
800 checkGLcall("glStencilOp(...)");
803 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
805 switch (op)
807 case WINED3D_STENCIL_OP_KEEP:
808 return GL_KEEP;
809 case WINED3D_STENCIL_OP_ZERO:
810 return GL_ZERO;
811 case WINED3D_STENCIL_OP_REPLACE:
812 return GL_REPLACE;
813 case WINED3D_STENCIL_OP_INCR_SAT:
814 return GL_INCR;
815 case WINED3D_STENCIL_OP_DECR_SAT:
816 return GL_DECR;
817 case WINED3D_STENCIL_OP_INVERT:
818 return GL_INVERT;
819 case WINED3D_STENCIL_OP_INCR:
820 return GL_INCR_WRAP_EXT;
821 case WINED3D_STENCIL_OP_DECR:
822 return GL_DECR_WRAP_EXT;
823 default:
824 FIXME("Unrecognized stencil op %#x.\n", op);
825 return GL_KEEP;
829 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
831 const struct wined3d_gl_info *gl_info = context->gl_info;
832 DWORD onesided_enable = FALSE;
833 DWORD twosided_enable = FALSE;
834 GLint func = GL_ALWAYS;
835 GLint func_ccw = GL_ALWAYS;
836 GLint ref = 0;
837 GLuint mask = 0;
838 GLint stencilFail = GL_KEEP;
839 GLint depthFail = GL_KEEP;
840 GLint stencilPass = GL_KEEP;
841 GLint stencilFail_ccw = GL_KEEP;
842 GLint depthFail_ccw = GL_KEEP;
843 GLint stencilPass_ccw = GL_KEEP;
845 /* No stencil test without a stencil buffer. */
846 if (!state->fb->depth_stencil)
848 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
849 checkGLcall("glDisable GL_STENCIL_TEST");
850 return;
853 onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
854 twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
855 if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
856 func = GL_ALWAYS;
857 if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
858 func_ccw = GL_ALWAYS;
859 ref = state->render_states[WINED3D_RS_STENCILREF];
860 mask = state->render_states[WINED3D_RS_STENCILMASK];
861 stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
862 depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
863 stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
864 stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
865 depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
866 stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
868 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
869 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
870 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
871 onesided_enable, twosided_enable, ref, mask,
872 func, stencilFail, depthFail, stencilPass,
873 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
875 if (twosided_enable && onesided_enable)
877 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
878 checkGLcall("glEnable GL_STENCIL_TEST");
880 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
882 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
883 * which has an effect on the code below too. If we apply the front face
884 * afterwards, we are sure that the active stencil face is set to front,
885 * and other stencil functions which do not use two sided stencil do not have
886 * to set it back
888 renderstate_stencil_twosided(context, GL_BACK,
889 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
890 renderstate_stencil_twosided(context, GL_FRONT,
891 func, ref, mask, stencilFail, depthFail, stencilPass);
893 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
895 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
896 checkGLcall("glStencilFuncSeparateATI(...)");
897 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
898 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
899 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
900 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
901 } else {
902 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
905 else if(onesided_enable)
907 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
909 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
910 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
913 /* This code disables the ATI extension as well, since the standard stencil functions are equal
914 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
916 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
917 checkGLcall("glEnable GL_STENCIL_TEST");
918 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
919 checkGLcall("glStencilFunc(...)");
920 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
921 checkGLcall("glStencilOp(...)");
923 else
925 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
926 checkGLcall("glDisable GL_STENCIL_TEST");
930 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
932 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
933 const struct wined3d_gl_info *gl_info = context->gl_info;
935 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
936 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
937 gl_info->gl_ops.gl.p_glStencilMask(mask);
938 checkGLcall("glStencilMask");
939 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
940 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
941 gl_info->gl_ops.gl.p_glStencilMask(mask);
944 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
946 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
947 const struct wined3d_gl_info *gl_info = context->gl_info;
949 gl_info->gl_ops.gl.p_glStencilMask(mask);
950 checkGLcall("glStencilMask");
953 void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
955 const struct wined3d_gl_info *gl_info = context->gl_info;
957 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
959 if (!state->render_states[WINED3D_RS_FOGENABLE])
960 return;
962 /* Table fog on: Never use fog coords, and use per-fragment fog */
963 if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
965 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST);
966 if (context->fog_coord)
968 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
969 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
970 context->fog_coord = FALSE;
973 /* Range fog is only used with per-vertex fog in d3d */
974 if (gl_info->supported[NV_FOG_DISTANCE])
976 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
977 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
979 return;
982 /* Otherwise use per-vertex fog in any case */
983 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_FASTEST);
985 if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
987 /* No fog at all, or transformed vertices: Use fog coord */
988 if (!context->fog_coord)
990 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
991 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
992 context->fog_coord = TRUE;
995 else
997 /* Otherwise, use the fragment depth */
998 if (context->fog_coord)
1000 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1001 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1002 context->fog_coord = FALSE;
1005 if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
1007 if (gl_info->supported[NV_FOG_DISTANCE])
1009 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1010 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1012 else
1014 WARN("Range fog enabled, but not supported by this GL implementation.\n");
1017 else if (gl_info->supported[NV_FOG_DISTANCE])
1019 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1020 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1025 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1027 const struct wined3d_gl_info *gl_info = context->gl_info;
1028 float fogstart, fogend;
1029 union {
1030 DWORD d;
1031 float f;
1032 } tmpvalue;
1034 switch(context->fog_source) {
1035 case FOGSOURCE_VS:
1036 fogstart = 1.0f;
1037 fogend = 0.0f;
1038 break;
1040 case FOGSOURCE_COORD:
1041 fogstart = 255.0f;
1042 fogend = 0.0f;
1043 break;
1045 case FOGSOURCE_FFP:
1046 tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
1047 fogstart = tmpvalue.f;
1048 tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
1049 fogend = tmpvalue.f;
1050 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
1051 if(fogstart == fogend) {
1052 fogstart = -INFINITY;
1053 fogend = 0.0f;
1055 break;
1057 default:
1058 /* This should not happen.context->fog_source is set in wined3d, not the app.
1059 * Still this is needed to make the compiler happy
1061 ERR("Unexpected fog coordinate source\n");
1062 fogstart = 0.0f;
1063 fogend = 0.0f;
1066 gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, fogstart);
1067 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1068 TRACE("Fog Start == %f\n", fogstart);
1070 gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, fogend);
1071 checkGLcall("glFogf(GL_FOG_END, fogend)");
1072 TRACE("Fog End == %f\n", fogend);
1075 void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1077 const struct wined3d_gl_info *gl_info = context->gl_info;
1078 enum fogsource new_source;
1080 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
1082 if (!state->render_states[WINED3D_RS_FOGENABLE])
1084 /* No fog? Disable it, and we're done :-) */
1085 glDisableWINE(GL_FOG);
1086 checkGLcall("glDisable GL_FOG");
1087 return;
1090 /* Fog Rules:
1092 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1093 * It can use the Z value of the vertex, or the alpha component of the specular color.
1094 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1095 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1096 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1098 * FOGTABLEMODE != NONE:
1099 * The Z value is used, with the equation specified, no matter what vertex type.
1101 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1102 * Per vertex fog is calculated using the specified fog equation and the parameters
1104 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1105 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1106 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1109 * Rules for vertex fog with shaders:
1111 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1112 * the fog computation to happen during transformation while openGL expects it to happen
1113 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1114 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1115 * To solve this problem, WineD3D does:
1116 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1117 * shader,
1118 * and 2) disables the fog computation (in either the fixed function or programmable
1119 * rasterizer) if using a vertex program.
1121 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1122 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1123 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1124 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1125 * There are some GL differences between specular fog coords and vertex shaders though.
1127 * With table fog the vertex shader fog coordinate is ignored.
1129 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1130 * without shaders).
1133 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1134 * the system will apply only pixel(=table) fog effects."
1136 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
1138 if (use_vs(state))
1140 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1141 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1142 new_source = FOGSOURCE_VS;
1144 else
1146 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
1148 /* If processed vertices are used, fall through to the NONE case */
1149 case WINED3D_FOG_EXP:
1150 if (!context->last_was_rhw)
1152 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1153 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1154 new_source = FOGSOURCE_FFP;
1155 break;
1157 /* drop through */
1159 case WINED3D_FOG_EXP2:
1160 if (!context->last_was_rhw)
1162 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1163 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1164 new_source = FOGSOURCE_FFP;
1165 break;
1167 /* drop through */
1169 case WINED3D_FOG_LINEAR:
1170 if (!context->last_was_rhw)
1172 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1173 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1174 new_source = FOGSOURCE_FFP;
1175 break;
1177 /* drop through */
1179 case WINED3D_FOG_NONE:
1180 /* Both are none? According to msdn the alpha channel of the specular
1181 * color contains a fog factor. Set it in drawStridedSlow.
1182 * Same happens with Vertexfog on transformed vertices
1184 new_source = FOGSOURCE_COORD;
1185 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1186 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1187 break;
1189 default:
1190 FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
1191 state->render_states[WINED3D_RS_FOGVERTEXMODE]);
1192 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1195 } else {
1196 new_source = FOGSOURCE_FFP;
1198 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
1200 case WINED3D_FOG_EXP:
1201 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1202 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1203 break;
1205 case WINED3D_FOG_EXP2:
1206 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1207 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1208 break;
1210 case WINED3D_FOG_LINEAR:
1211 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1212 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1213 break;
1215 case WINED3D_FOG_NONE: /* Won't happen */
1216 default:
1217 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
1218 state->render_states[WINED3D_RS_FOGTABLEMODE]);
1222 glEnableWINE(GL_FOG);
1223 checkGLcall("glEnable GL_FOG");
1224 if (new_source != context->fog_source)
1226 context->fog_source = new_source;
1227 state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
1231 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1233 const struct wined3d_gl_info *gl_info = context->gl_info;
1234 float col[4];
1236 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
1237 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, &col[0]);
1238 checkGLcall("glFog GL_FOG_COLOR");
1241 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1243 const struct wined3d_gl_info *gl_info = context->gl_info;
1244 union {
1245 DWORD d;
1246 float f;
1247 } tmpvalue;
1249 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1250 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1251 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1254 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1256 const struct wined3d_device *device = context->swapchain->device;
1257 const struct wined3d_gl_info *gl_info = context->gl_info;
1258 GLenum Parm = 0;
1260 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1261 * The vertex declaration will call this function if the fixed function pipeline is used.
1264 if(isStateDirty(context, STATE_VDECL)) {
1265 return;
1268 context->num_untracked_materials = 0;
1269 if ((device->stream_info.use_map & (1 << WINED3D_FFP_DIFFUSE))
1270 && state->render_states[WINED3D_RS_COLORVERTEX])
1272 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1273 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
1274 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
1275 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
1276 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
1278 if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1280 if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1281 Parm = GL_AMBIENT_AND_DIFFUSE;
1282 else
1283 Parm = GL_DIFFUSE;
1284 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1286 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1287 context->num_untracked_materials++;
1289 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1291 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1292 context->num_untracked_materials++;
1295 else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1297 Parm = GL_AMBIENT;
1298 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1300 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1301 context->num_untracked_materials++;
1303 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1305 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1306 context->num_untracked_materials++;
1309 else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1311 Parm = GL_EMISSION;
1312 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1314 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1315 context->num_untracked_materials++;
1318 else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1320 Parm = GL_SPECULAR;
1324 /* Nothing changed, return. */
1325 if (Parm == context->tracking_parm) return;
1327 if (!Parm)
1329 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_MATERIAL);
1330 checkGLcall("glDisable GL_COLOR_MATERIAL");
1332 else
1334 gl_info->gl_ops.gl.p_glColorMaterial(GL_FRONT_AND_BACK, Parm);
1335 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1336 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_MATERIAL);
1337 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1340 /* Apparently calls to glMaterialfv are ignored for properties we're
1341 * tracking with glColorMaterial, so apply those here. */
1342 switch (context->tracking_parm)
1344 case GL_AMBIENT_AND_DIFFUSE:
1345 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1346 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1347 checkGLcall("glMaterialfv");
1348 break;
1350 case GL_DIFFUSE:
1351 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1352 checkGLcall("glMaterialfv");
1353 break;
1355 case GL_AMBIENT:
1356 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1357 checkGLcall("glMaterialfv");
1358 break;
1360 case GL_EMISSION:
1361 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
1362 checkGLcall("glMaterialfv");
1363 break;
1365 case GL_SPECULAR:
1366 /* Only change material color if specular is enabled, otherwise it is set to black */
1367 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1369 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
1370 checkGLcall("glMaterialfv");
1372 else
1374 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1375 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1376 checkGLcall("glMaterialfv");
1378 break;
1381 context->tracking_parm = Parm;
1384 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1386 const struct wined3d_gl_info *gl_info = context->gl_info;
1387 union
1389 DWORD d;
1390 struct wined3d_line_pattern lp;
1391 } tmppattern;
1392 tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
1394 TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1396 if (tmppattern.lp.repeat_factor)
1398 gl_info->gl_ops.gl.p_glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1399 checkGLcall("glLineStipple(repeat, linepattern)");
1400 gl_info->gl_ops.gl.p_glEnable(GL_LINE_STIPPLE);
1401 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1403 else
1405 gl_info->gl_ops.gl.p_glDisable(GL_LINE_STIPPLE);
1406 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1410 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1412 const struct wined3d_gl_info *gl_info = context->gl_info;
1414 if (isStateDirty(context, STATE_VDECL))
1415 return;
1417 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1418 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1419 * by zero and is not properly defined in opengl, so avoid it
1421 if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
1422 && (context->swapchain->device->stream_info.use_map & (1 << WINED3D_FFP_NORMAL)))
1424 gl_info->gl_ops.gl.p_glEnable(GL_NORMALIZE);
1425 checkGLcall("glEnable(GL_NORMALIZE);");
1427 else
1429 gl_info->gl_ops.gl.p_glDisable(GL_NORMALIZE);
1430 checkGLcall("glDisable(GL_NORMALIZE);");
1434 void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1436 union {
1437 DWORD d;
1438 float f;
1439 } tmpvalue;
1441 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1442 if (tmpvalue.f != 1.0f)
1444 FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1446 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1447 if (tmpvalue.f != 64.0f)
1449 FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1454 void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1456 const struct wined3d_gl_info *gl_info = context->gl_info;
1457 union
1459 DWORD d;
1460 float f;
1461 } min, max;
1463 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1464 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1466 /* Max point size trumps min point size */
1467 if(min.f > max.f) {
1468 min.f = max.f;
1471 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1472 checkGLcall("glPointParameterfEXT(...)");
1473 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1474 checkGLcall("glPointParameterfEXT(...)");
1477 void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1479 const struct wined3d_gl_info *gl_info = context->gl_info;
1480 union
1482 DWORD d;
1483 float f;
1484 } min, max;
1486 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1487 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1489 /* Max point size trumps min point size */
1490 if(min.f > max.f) {
1491 min.f = max.f;
1494 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1495 checkGLcall("glPointParameterfARB(...)");
1496 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1497 checkGLcall("glPointParameterfARB(...)");
1500 void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1502 const struct wined3d_gl_info *gl_info = context->gl_info;
1503 /* TODO: Group this with the viewport */
1505 * POINTSCALEENABLE controls how point size value is treated. If set to
1506 * true, the point size is scaled with respect to height of viewport.
1507 * When set to false point size is in pixels.
1510 /* Default values */
1511 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1512 union {
1513 DWORD d;
1514 float f;
1515 } pointSize, A, B, C;
1517 pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
1518 A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
1519 B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
1520 C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
1522 if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1524 DWORD h = state->viewport.height;
1525 GLfloat scaleFactor;
1527 if (pointSize.f < gl_info->limits.pointsize_min)
1529 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1530 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1531 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1532 * are less than 1.0f. scale_factor = 1.0f / point_size.
1534 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1535 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1536 * is 1.0, but then accepts points below that and draws too small points
1538 pointSize.f = gl_info->limits.pointsize_min;
1540 else if(pointSize.f > gl_info->limits.pointsize_max)
1542 /* gl already scales the input to glPointSize,
1543 * d3d scales the result after the point size scale.
1544 * If the point size is bigger than the max size, use the
1545 * scaling to scale it bigger, and set the gl point size to max
1547 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1548 TRACE("scale: %f\n", scaleFactor);
1549 pointSize.f = gl_info->limits.pointsize_max;
1550 } else {
1551 scaleFactor = 1.0f;
1553 scaleFactor = powf(h * scaleFactor, 2);
1555 att[0] = A.f / scaleFactor;
1556 att[1] = B.f / scaleFactor;
1557 att[2] = C.f / scaleFactor;
1560 if (gl_info->supported[ARB_POINT_PARAMETERS])
1562 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1563 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1565 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1567 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1568 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1570 else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1572 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1575 gl_info->gl_ops.gl.p_glPointSize(pointSize.f);
1576 checkGLcall("glPointSize(...);");
1579 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1581 WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
1584 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1586 DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
1587 DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
1588 DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
1589 DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
1590 const struct wined3d_gl_info *gl_info = context->gl_info;
1592 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1593 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1594 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1595 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1596 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1597 gl_info->gl_ops.gl.p_glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1598 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1599 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1600 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1601 checkGLcall("glColorMask(...)");
1603 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1604 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1606 FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1607 mask0, mask1, mask2, mask3);
1608 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1612 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1614 GL_EXTCALL(glColorMaskIndexedEXT(index,
1615 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1616 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1617 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1618 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1621 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1623 set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
1626 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1628 set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
1631 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1633 set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
1636 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1638 set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
1641 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1643 const struct wined3d_gl_info *gl_info = context->gl_info;
1645 if (state->render_states[WINED3D_RS_LOCALVIEWER])
1647 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1648 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1650 else
1652 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1653 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1657 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1659 if (state->render_states[WINED3D_RS_LASTPIXEL])
1661 TRACE("Last Pixel Drawing Enabled\n");
1663 else
1665 static BOOL warned;
1666 if (!warned) {
1667 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1668 warned = TRUE;
1669 } else {
1670 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1675 void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1677 static BOOL warned;
1679 /* TODO: NV_POINT_SPRITE */
1680 if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1682 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1683 FIXME("Point sprites not supported\n");
1684 warned = TRUE;
1688 void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1690 const struct wined3d_gl_info *gl_info = context->gl_info;
1692 if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1694 gl_info->gl_ops.gl.p_glEnable(GL_POINT_SPRITE_ARB);
1695 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1697 else
1699 gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
1700 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1704 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1706 if (state->render_states[WINED3D_RS_WRAP0]
1707 || state->render_states[WINED3D_RS_WRAP1]
1708 || state->render_states[WINED3D_RS_WRAP2]
1709 || state->render_states[WINED3D_RS_WRAP3]
1710 || state->render_states[WINED3D_RS_WRAP4]
1711 || state->render_states[WINED3D_RS_WRAP5]
1712 || state->render_states[WINED3D_RS_WRAP6]
1713 || state->render_states[WINED3D_RS_WRAP7]
1714 || state->render_states[WINED3D_RS_WRAP8]
1715 || state->render_states[WINED3D_RS_WRAP9]
1716 || state->render_states[WINED3D_RS_WRAP10]
1717 || state->render_states[WINED3D_RS_WRAP11]
1718 || state->render_states[WINED3D_RS_WRAP12]
1719 || state->render_states[WINED3D_RS_WRAP13]
1720 || state->render_states[WINED3D_RS_WRAP14]
1721 || state->render_states[WINED3D_RS_WRAP15])
1722 FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
1725 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1727 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1728 WARN("Multisample antialiasing not supported by GL.\n");
1731 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1733 const struct wined3d_gl_info *gl_info = context->gl_info;
1735 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1737 gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE_ARB);
1738 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1740 else
1742 gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE_ARB);
1743 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1747 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1749 const struct wined3d_gl_info *gl_info = context->gl_info;
1751 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
1753 gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST);
1754 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1756 else
1758 gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
1759 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1763 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1764 * OpenGL the bias is specified in units of "the smallest value that is
1765 * guaranteed to produce a resolvable offset for a given implementation". To
1766 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1767 * There's no practical way to retrieve that value from a given GL
1768 * implementation, but the D3D application has essentially the same problem,
1769 * which makes a guess of the depth buffer format's highest possible value a
1770 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1771 * depth slope, and doesn't need to be scaled. */
1772 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1774 const struct wined3d_gl_info *gl_info = context->gl_info;
1776 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
1777 || state->render_states[WINED3D_RS_DEPTHBIAS])
1779 const struct wined3d_surface *depth = state->fb->depth_stencil;
1780 float scale;
1782 union
1784 DWORD d;
1785 float f;
1786 } scale_bias, const_bias;
1788 scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
1789 const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
1791 gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL);
1792 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1794 if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
1796 float bias = -(float)const_bias.d;
1797 gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias);
1798 checkGLcall("glPolygonOffset");
1800 else
1802 if (depth)
1804 const struct wined3d_format *fmt = depth->resource.format;
1805 scale = powf(2, fmt->depth_size) - 1;
1806 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
1807 debug_d3dformat(fmt->id), scale);
1809 else
1811 /* The context manager will reapply this state on a depth stencil change */
1812 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
1813 scale = 0.0f;
1816 gl_info->gl_ops.gl.p_glPolygonOffset(scale_bias.f, const_bias.f * scale);
1817 checkGLcall("glPolygonOffset(...)");
1820 else
1822 gl_info->gl_ops.gl.p_glDisable(GL_POLYGON_OFFSET_FILL);
1823 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1827 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1829 if (state->render_states[WINED3D_RS_ZVISIBLE])
1830 FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
1833 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1835 const struct wined3d_gl_info *gl_info = context->gl_info;
1837 if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
1839 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1840 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1842 else
1844 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1845 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1849 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1851 if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
1852 FIXME("Stippled Alpha not supported yet.\n");
1855 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1857 if (state->render_states[WINED3D_RS_ANTIALIAS])
1858 FIXME("Antialias not supported yet.\n");
1861 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1863 if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
1864 FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
1865 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
1868 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1870 if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
1871 FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
1872 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
1875 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1877 union {
1878 DWORD d;
1879 float f;
1880 } tmpvalue;
1881 tmpvalue.f = 1.0f;
1883 if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
1885 static BOOL displayed = FALSE;
1887 tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
1888 if(!displayed)
1889 FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1891 displayed = TRUE;
1895 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1897 if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
1898 FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
1899 state->render_states[WINED3D_RS_POSITIONDEGREE]);
1902 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1904 if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
1905 FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
1906 state->render_states[WINED3D_RS_NORMALDEGREE]);
1909 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1911 if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
1912 FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1913 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
1916 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1918 union {
1919 DWORD d;
1920 float f;
1921 } zmin, zmax;
1923 const struct wined3d_gl_info *gl_info = context->gl_info;
1925 if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1927 zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
1928 zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
1930 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1931 * In d3d9 test is not performed in this case*/
1932 if (zmin.f <= zmax.f)
1934 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1935 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1936 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1937 checkGLcall("glDepthBoundsEXT(...)");
1939 else
1941 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1942 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1945 else
1947 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1948 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1951 state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
1954 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1956 if (state->render_states[WINED3D_RS_WRAPU])
1957 FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
1960 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1962 if (state->render_states[WINED3D_RS_WRAPV])
1963 FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
1966 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1968 if (state->render_states[WINED3D_RS_MONOENABLE])
1969 FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
1972 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1974 if (state->render_states[WINED3D_RS_ROP2])
1975 FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
1978 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1980 if (state->render_states[WINED3D_RS_PLANEMASK])
1981 FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
1984 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1986 if (state->render_states[WINED3D_RS_SUBPIXEL])
1987 FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
1990 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1992 if (state->render_states[WINED3D_RS_SUBPIXELX])
1993 FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
1996 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1998 if (state->render_states[WINED3D_RS_STIPPLEENABLE])
1999 FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
2002 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2004 if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
2005 FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
2008 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2010 if (state->render_states[WINED3D_RS_ANISOTROPY])
2011 FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
2014 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2016 if (state->render_states[WINED3D_RS_FLUSHBATCH])
2017 FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
2020 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2022 if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
2023 FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
2026 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2028 if (state->render_states[WINED3D_RS_EXTENTS])
2029 FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
2032 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2034 if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
2035 FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
2038 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2040 if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
2041 FIXME("Software vertex processing not implemented.\n");
2044 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2045 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2046 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2047 * flag specifies the complement of the input should be used. */
2048 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2049 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2051 /* Calculate the operand */
2052 if (complement) {
2053 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2054 else *operand = GL_ONE_MINUS_SRC_COLOR;
2055 } else {
2056 if (from_alpha) *operand = GL_SRC_ALPHA;
2057 else *operand = GL_SRC_COLOR;
2060 /* Calculate the source */
2061 switch (arg & WINED3DTA_SELECTMASK) {
2062 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2063 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2064 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2065 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2066 case WINED3DTA_SPECULAR:
2068 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2069 * 'Secondary color' and isn't supported until base GL supports it
2070 * There is no concept of temp registers as far as I can tell
2072 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2073 *source = GL_TEXTURE;
2074 break;
2075 default:
2076 FIXME("Unrecognized texture arg %#x\n", arg);
2077 *source = GL_TEXTURE;
2078 break;
2082 /* Setup the texture operations texture stage states */
2083 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2084 BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2086 GLenum src1, src2, src3;
2087 GLenum opr1, opr2, opr3;
2088 GLenum comb_target;
2089 GLenum src0_target, src1_target, src2_target;
2090 GLenum opr0_target, opr1_target, opr2_target;
2091 GLenum scal_target;
2092 GLenum opr=0, invopr, src3_target, opr3_target;
2093 BOOL Handled = FALSE;
2095 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2097 /* This is called by a state handler which has the gl lock held and a context for the thread */
2099 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2100 the form (a1 <operation> a2). However, some of the more complex operations
2101 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2102 in a third parameter called a0. Therefore these are operations of the form
2103 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2105 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2106 functions below, expect their syntax to differ slightly to those listed in the
2107 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2108 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2110 if (isAlpha)
2112 comb_target = GL_COMBINE_ALPHA;
2113 src0_target = GL_SOURCE0_ALPHA;
2114 src1_target = GL_SOURCE1_ALPHA;
2115 src2_target = GL_SOURCE2_ALPHA;
2116 opr0_target = GL_OPERAND0_ALPHA;
2117 opr1_target = GL_OPERAND1_ALPHA;
2118 opr2_target = GL_OPERAND2_ALPHA;
2119 scal_target = GL_ALPHA_SCALE;
2121 else
2123 comb_target = GL_COMBINE_RGB;
2124 src0_target = GL_SOURCE0_RGB;
2125 src1_target = GL_SOURCE1_RGB;
2126 src2_target = GL_SOURCE2_RGB;
2127 opr0_target = GL_OPERAND0_RGB;
2128 opr1_target = GL_OPERAND1_RGB;
2129 opr2_target = GL_OPERAND2_RGB;
2130 scal_target = GL_RGB_SCALE;
2133 /* If a texture stage references an invalid texture unit the stage just
2134 * passes through the result from the previous stage */
2135 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2137 arg1 = WINED3DTA_CURRENT;
2138 op = WINED3D_TOP_SELECT_ARG1;
2141 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2143 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2144 } else {
2145 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2147 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2148 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2150 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2152 Handled = TRUE; /* Assume will be handled */
2154 /* Other texture operations require special extensions: */
2155 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2157 if (isAlpha) {
2158 opr = GL_SRC_ALPHA;
2159 invopr = GL_ONE_MINUS_SRC_ALPHA;
2160 src3_target = GL_SOURCE3_ALPHA_NV;
2161 opr3_target = GL_OPERAND3_ALPHA_NV;
2162 } else {
2163 opr = GL_SRC_COLOR;
2164 invopr = GL_ONE_MINUS_SRC_COLOR;
2165 src3_target = GL_SOURCE3_RGB_NV;
2166 opr3_target = GL_OPERAND3_RGB_NV;
2168 switch (op)
2170 case WINED3D_TOP_DISABLE: /* Only for alpha */
2171 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2172 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2173 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2174 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2175 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2176 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2177 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2178 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2179 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2180 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2181 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2182 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2183 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2184 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2185 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2186 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2187 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2188 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2189 break;
2191 case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
2192 case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
2193 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2194 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2195 if (op == WINED3D_TOP_SELECT_ARG1)
2197 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2198 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2199 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2200 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2202 else
2204 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2205 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2206 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2207 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2209 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2210 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2211 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2212 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2213 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2214 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2215 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2216 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2217 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2218 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2219 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2220 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2221 break;
2223 case WINED3D_TOP_MODULATE:
2224 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2225 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2226 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2227 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2228 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2229 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2230 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2231 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2232 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2233 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2234 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2235 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2236 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2237 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2238 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2239 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2240 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2241 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2242 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2243 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2244 break;
2245 case WINED3D_TOP_MODULATE_2X:
2246 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2247 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2248 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2249 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2250 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2251 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2252 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2253 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2254 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2255 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2256 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2257 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2258 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2259 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2260 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2261 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2262 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2263 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2264 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2265 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2266 break;
2267 case WINED3D_TOP_MODULATE_4X:
2268 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2269 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2270 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2271 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2272 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2273 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2274 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2275 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2276 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2277 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2278 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2279 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2280 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2281 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2282 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2283 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2284 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2285 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2286 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2287 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2288 break;
2290 case WINED3D_TOP_ADD:
2291 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2292 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2293 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2294 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2295 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2296 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2297 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2298 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2299 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2300 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2301 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2302 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2303 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2304 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2305 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2306 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2307 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2308 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2309 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2310 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2311 break;
2313 case WINED3D_TOP_ADD_SIGNED:
2314 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2315 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2316 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2317 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2318 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2319 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2320 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2321 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2322 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2323 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2324 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2325 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2326 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2327 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2328 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2329 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2330 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2331 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2332 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2333 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2334 break;
2336 case WINED3D_TOP_ADD_SIGNED_2X:
2337 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2338 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2339 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2340 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2341 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2342 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2343 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2344 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2345 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2346 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2347 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2348 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2349 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2350 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2351 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2352 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2353 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2354 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2355 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2356 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2357 break;
2359 case WINED3D_TOP_ADD_SMOOTH:
2360 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2361 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2362 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2363 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2364 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2365 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2366 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2367 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2368 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2369 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2370 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2371 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2372 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2373 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2374 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2375 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2376 switch (opr1) {
2377 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2378 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2379 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2380 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2382 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2383 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2384 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2385 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2386 break;
2388 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2389 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2390 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2391 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2392 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2393 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2394 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2395 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
2396 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
2397 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2398 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2399 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2400 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2401 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2402 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2403 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
2404 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
2405 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2406 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2407 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2408 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2409 break;
2410 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2411 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2412 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2413 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2414 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2415 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2416 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2417 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2418 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2419 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2420 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2421 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2422 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2423 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2424 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2425 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2426 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2427 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2428 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2429 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2430 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2431 break;
2432 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2433 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2434 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2435 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2436 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2437 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2438 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2439 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
2440 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
2441 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2442 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2443 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2444 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2445 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2446 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2447 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
2448 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
2449 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2450 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2451 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2452 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2453 break;
2454 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2455 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2456 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2457 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2458 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2459 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2460 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2461 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2462 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2463 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2464 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2465 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2466 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2467 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2468 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2469 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2470 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2471 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2472 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2473 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2474 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2475 break;
2476 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2477 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2478 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2479 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2480 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2481 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2482 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2483 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2484 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2485 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2486 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2487 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2488 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2489 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2490 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2491 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2492 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2493 switch (opr) {
2494 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2495 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2497 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2498 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2499 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2500 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2501 break;
2502 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2503 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2504 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2505 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2506 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2507 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2508 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2509 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2510 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2511 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2512 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2513 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2514 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2515 switch (opr1) {
2516 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2517 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2519 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2520 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2521 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2522 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2523 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2524 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2525 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2526 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2527 break;
2528 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2529 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2530 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2531 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2532 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2533 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2534 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2535 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2536 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2537 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2538 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2539 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2540 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2541 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2542 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2543 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2544 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2545 switch (opr1) {
2546 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2547 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2548 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2549 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2551 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2552 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2553 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2554 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2555 break;
2556 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2557 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2558 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2559 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2560 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2561 switch (opr1) {
2562 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2563 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2564 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2565 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2567 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2568 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2569 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2570 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2571 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2572 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2573 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2574 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2575 switch (opr1) {
2576 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2577 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2579 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2580 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2581 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2582 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2583 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2584 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2585 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2586 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2587 break;
2588 case WINED3D_TOP_MULTIPLY_ADD:
2589 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2590 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2591 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2592 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2593 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2594 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2595 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2596 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2597 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2598 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2599 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2600 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2601 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2602 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2603 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2604 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2605 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2606 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2607 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2608 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2609 break;
2611 case WINED3D_TOP_BUMPENVMAP:
2612 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
2613 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2614 Handled = FALSE;
2615 break;
2617 default:
2618 Handled = FALSE;
2620 if (Handled)
2622 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2623 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2625 return;
2627 } /* GL_NV_texture_env_combine4 */
2629 Handled = TRUE; /* Again, assume handled */
2630 switch (op) {
2631 case WINED3D_TOP_DISABLE: /* Only for alpha */
2632 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2633 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2634 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2635 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2636 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2637 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2638 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2639 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2640 break;
2641 case WINED3D_TOP_SELECT_ARG1:
2642 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2643 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2644 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2645 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2646 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2647 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2648 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2649 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2650 break;
2651 case WINED3D_TOP_SELECT_ARG2:
2652 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2653 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2654 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2655 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2656 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2657 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2658 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2659 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2660 break;
2661 case WINED3D_TOP_MODULATE:
2662 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2663 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2664 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2665 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2666 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2667 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2668 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2669 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2670 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2671 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2672 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2673 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2674 break;
2675 case WINED3D_TOP_MODULATE_2X:
2676 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2677 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2678 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2679 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2680 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2681 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2682 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2683 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2684 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2685 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2686 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2687 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2688 break;
2689 case WINED3D_TOP_MODULATE_4X:
2690 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2691 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2692 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2693 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2694 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2695 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2696 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2697 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2698 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2699 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2700 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2701 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2702 break;
2703 case WINED3D_TOP_ADD:
2704 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2705 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2706 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2707 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2708 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2709 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2710 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2711 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2712 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2713 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2714 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2715 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2716 break;
2717 case WINED3D_TOP_ADD_SIGNED:
2718 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2719 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2720 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2721 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2722 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2723 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2724 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2725 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2726 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2727 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2728 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2729 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2730 break;
2731 case WINED3D_TOP_ADD_SIGNED_2X:
2732 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2733 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2734 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2735 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2736 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2737 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2738 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2739 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2740 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2741 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2742 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2743 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2744 break;
2745 case WINED3D_TOP_SUBTRACT:
2746 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2748 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2749 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2750 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2751 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2752 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2753 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2754 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2755 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2756 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2757 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2758 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2759 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2760 } else {
2761 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2763 break;
2765 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2766 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2767 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2768 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2769 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2770 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2771 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2772 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2773 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2774 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2775 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2776 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
2777 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2778 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2779 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2780 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2781 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2782 break;
2783 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2784 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2785 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2786 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2787 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2788 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2789 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2790 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2791 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2792 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2793 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2794 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2795 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2796 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2797 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2798 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2799 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2800 break;
2801 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2802 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2803 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2804 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2805 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2806 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2807 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2808 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2809 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2810 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2811 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2812 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
2813 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2814 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2815 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2816 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2817 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2818 break;
2819 case WINED3D_TOP_BLEND_CURRENT_ALPHA:
2820 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2821 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2822 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2823 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2824 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2825 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2826 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2827 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2828 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2829 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2830 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
2831 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2832 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2833 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2834 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2835 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2836 break;
2837 case WINED3D_TOP_DOTPRODUCT3:
2838 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2840 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2841 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2843 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2845 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2846 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2847 } else {
2848 FIXME("This version of opengl does not support GL_DOT3\n");
2850 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2851 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2852 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2853 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2854 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2855 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2856 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2857 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2858 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2859 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2860 break;
2861 case WINED3D_TOP_LERP:
2862 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2863 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2864 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2865 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2866 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2867 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2868 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2869 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2870 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2871 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2872 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2873 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2874 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2875 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2876 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2877 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2878 break;
2879 case WINED3D_TOP_ADD_SMOOTH:
2880 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2882 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2883 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2884 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2885 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2886 switch (opr1) {
2887 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2888 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2889 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2890 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2892 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2893 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2894 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2895 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2896 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2897 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2898 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2899 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2900 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2901 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2902 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2903 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2904 } else
2905 Handled = FALSE;
2906 break;
2907 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2908 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2910 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2911 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2912 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2913 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2914 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2915 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2916 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2917 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2918 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2919 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2920 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2921 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2922 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2923 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2924 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2925 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2926 } else
2927 Handled = FALSE;
2928 break;
2929 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2930 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2932 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2933 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2934 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2935 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2936 switch (opr1) {
2937 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2938 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2939 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2940 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2942 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2943 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2944 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2945 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2946 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2947 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2948 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2949 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2950 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2951 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2952 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2953 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2954 } else
2955 Handled = FALSE;
2956 break;
2957 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2958 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2960 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2961 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2962 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2963 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2964 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2965 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2966 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2967 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2968 switch (opr1) {
2969 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2970 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2971 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2972 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2974 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2975 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2976 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2977 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2978 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2979 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2980 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2981 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2982 } else
2983 Handled = FALSE;
2984 break;
2985 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2986 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2988 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2989 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2990 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2991 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2992 switch (opr1) {
2993 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2994 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2995 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2996 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2998 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2999 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3000 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3001 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3002 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
3003 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
3004 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3005 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3006 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3007 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3008 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3009 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3010 } else
3011 Handled = FALSE;
3012 break;
3013 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3014 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3016 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3017 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3018 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3019 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3020 switch (opr1) {
3021 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
3022 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
3023 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3024 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3026 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3027 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3028 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3029 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3030 switch (opr1) {
3031 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3032 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3033 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3034 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3036 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
3037 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
3038 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3039 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3040 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3041 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3042 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3043 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3044 } else
3045 Handled = FALSE;
3046 break;
3047 case WINED3D_TOP_MULTIPLY_ADD:
3048 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3050 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3051 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3052 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3053 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3054 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3055 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3056 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3057 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3058 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3059 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3060 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3061 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3062 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3063 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3064 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3065 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3066 } else
3067 Handled = FALSE;
3068 break;
3069 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3070 case WINED3D_TOP_BUMPENVMAP:
3071 if (gl_info->supported[NV_TEXTURE_SHADER2])
3073 /* Technically texture shader support without register combiners is possible, but not expected to occur
3074 * on real world cards, so for now a fixme should be enough
3076 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3078 Handled = FALSE;
3079 break;
3081 default:
3082 Handled = FALSE;
3085 if (Handled) {
3086 BOOL combineOK = TRUE;
3087 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3089 DWORD op2;
3091 if (isAlpha)
3092 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3093 else
3094 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3096 /* Note: If COMBINE4 in effect can't go back to combine! */
3097 switch (op2)
3099 case WINED3D_TOP_ADD_SMOOTH:
3100 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3101 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3102 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3103 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3104 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3105 case WINED3D_TOP_MULTIPLY_ADD:
3106 /* Ignore those implemented in both cases */
3107 switch (op)
3109 case WINED3D_TOP_SELECT_ARG1:
3110 case WINED3D_TOP_SELECT_ARG2:
3111 combineOK = FALSE;
3112 Handled = FALSE;
3113 break;
3114 default:
3115 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3116 return;
3121 if (combineOK)
3123 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3124 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3126 return;
3130 /* After all the extensions, if still unhandled, report fixme */
3131 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3135 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3137 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3138 const struct wined3d_device *device = context->swapchain->device;
3139 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3140 DWORD mapped_stage = device->texUnitMap[stage];
3141 const struct wined3d_gl_info *gl_info = context->gl_info;
3143 TRACE("Setting color op for stage %d\n", stage);
3145 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3146 if (use_ps(state)) return;
3148 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3150 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3152 if (tex_used && mapped_stage >= gl_info->limits.textures)
3154 FIXME("Attempt to enable unsupported stage!\n");
3155 return;
3157 context_active_texture(context, gl_info, mapped_stage);
3160 if (stage >= state->lowest_disabled_stage)
3162 TRACE("Stage disabled\n");
3163 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3165 /* Disable everything here */
3166 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3167 checkGLcall("glDisable(GL_TEXTURE_2D)");
3168 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3169 checkGLcall("glDisable(GL_TEXTURE_3D)");
3170 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3172 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3173 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3175 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3177 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3178 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3181 /* All done */
3182 return;
3185 /* The sampler will also activate the correct texture dimensions, so no
3186 * need to do it here if the sampler for this stage is dirty. */
3187 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3188 texture_activate_dimensions(state->textures[stage], gl_info);
3190 set_tex_op(gl_info, state, FALSE, stage,
3191 state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3192 state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3193 state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3194 state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3197 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3199 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3200 const struct wined3d_device *device = context->swapchain->device;
3201 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3202 DWORD mapped_stage = device->texUnitMap[stage];
3203 const struct wined3d_gl_info *gl_info = context->gl_info;
3204 DWORD op, arg1, arg2, arg0;
3206 TRACE("Setting alpha op for stage %d\n", stage);
3207 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3208 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3210 if (tex_used && mapped_stage >= gl_info->limits.textures)
3212 FIXME("Attempt to enable unsupported stage!\n");
3213 return;
3215 context_active_texture(context, gl_info, mapped_stage);
3218 op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3219 arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3220 arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3221 arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3223 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3225 struct wined3d_texture *texture = state->textures[0];
3226 GLenum texture_dimensions = texture->target;
3228 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3230 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3232 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3234 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3235 * properly. On the other hand applications can still use texture combiners apparently. This code
3236 * takes care that apps cannot remove the texture's alpha channel entirely.
3238 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3239 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3240 * and alpha component of diffuse color to draw things like translucent text and perform other
3241 * blending effects.
3243 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3244 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3245 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3246 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3247 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3248 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3249 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3250 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3251 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3252 * alpha.
3254 * What to do with multitexturing? So far no app has been found that uses color keying with
3255 * multitexturing */
3256 if (op == WINED3D_TOP_DISABLE)
3258 arg1 = WINED3DTA_TEXTURE;
3259 op = WINED3D_TOP_SELECT_ARG1;
3261 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3263 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3265 arg2 = WINED3DTA_TEXTURE;
3266 op = WINED3D_TOP_MODULATE;
3268 else arg1 = WINED3DTA_TEXTURE;
3270 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3272 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3274 arg1 = WINED3DTA_TEXTURE;
3275 op = WINED3D_TOP_MODULATE;
3277 else arg2 = WINED3DTA_TEXTURE;
3283 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3284 * this if block here, and the other code(color keying, texture unit selection) are the same
3286 TRACE("Setting alpha op for stage %d\n", stage);
3287 if (gl_info->supported[NV_REGISTER_COMBINERS])
3289 set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3290 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3292 else
3294 set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3298 void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3300 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3301 const struct wined3d_device *device = context->swapchain->device;
3302 const struct wined3d_gl_info *gl_info = context->gl_info;
3303 DWORD mapped_stage = device->texUnitMap[texUnit];
3304 BOOL generated;
3305 int coordIdx;
3307 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3308 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3310 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3311 return;
3314 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3315 if (mapped_stage >= gl_info->limits.textures) return;
3317 context_active_texture(context, gl_info, mapped_stage);
3318 generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3319 coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3321 set_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3322 state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3323 generated, context->last_was_rhw,
3324 device->stream_info.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3325 ? device->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3326 : WINED3DFMT_UNKNOWN,
3327 device->shader_backend->shader_has_ffp_proj_control(device->shader_priv));
3329 /* The sampler applying function calls us if this changes */
3330 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3332 if(generated) {
3333 FIXME("Non-power2 texture being used with generated texture coords\n");
3335 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3336 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3337 if (!use_ps(state))
3339 TRACE("Non power two matrix multiply fixup\n");
3340 gl_info->gl_ops.gl.p_glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3345 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3347 unsigned int texture_idx;
3349 for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3351 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3352 gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3356 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3357 GLuint *curVBO, const struct wined3d_state *state)
3359 const struct wined3d_device *device = context->swapchain->device;
3360 const struct wined3d_gl_info *gl_info = context->gl_info;
3361 unsigned int mapped_stage = 0;
3362 unsigned int textureNo = 0;
3364 for (textureNo = 0; textureNo < context->d3d_info->limits.ffp_blend_stages; ++textureNo)
3366 int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3368 mapped_stage = device->texUnitMap[textureNo];
3369 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3371 if (mapped_stage >= gl_info->limits.texture_coords)
3373 FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3374 continue;
3377 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3379 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3381 TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3382 textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3384 if (*curVBO != e->data.buffer_object)
3386 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3387 checkGLcall("glBindBufferARB");
3388 *curVBO = e->data.buffer_object;
3391 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3392 checkGLcall("glClientActiveTextureARB");
3394 /* The coords to supply depend completely on the fvf / vertex shader */
3395 gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3396 e->data.addr + state->load_base_vertex_index * e->stride);
3397 gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3399 else
3401 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3404 if (gl_info->supported[NV_REGISTER_COMBINERS])
3406 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3407 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3409 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3413 checkGLcall("loadTexCoords");
3416 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3418 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3419 const struct wined3d_device *device = context->swapchain->device;
3420 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3421 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3422 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3423 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3424 const struct wined3d_gl_info *gl_info = context->gl_info;
3425 DWORD mapped_stage = device->texUnitMap[stage];
3427 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3429 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3430 return;
3433 if (mapped_stage >= gl_info->limits.fragment_samplers)
3435 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3436 return;
3438 context_active_texture(context, gl_info, mapped_stage);
3440 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3442 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3443 * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3444 * means use the vertex position (camera-space) as the input texture coordinates
3445 * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3446 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3447 * to the TEXCOORDINDEX value
3449 switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3451 case WINED3DTSS_TCI_PASSTHRU:
3452 /* Use the specified texture coordinates contained within the
3453 * vertex format. This value resolves to zero. */
3454 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3455 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3456 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3457 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3458 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3459 break;
3461 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3462 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3463 * as the input texture coordinates for this stage's texture transformation. This
3464 * equates roughly to EYE_LINEAR */
3466 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3467 gl_info->gl_ops.gl.p_glPushMatrix();
3468 gl_info->gl_ops.gl.p_glLoadIdentity();
3469 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3470 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3471 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3472 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3473 gl_info->gl_ops.gl.p_glPopMatrix();
3474 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3476 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3477 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3478 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3479 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3481 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3482 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3483 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3484 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3486 break;
3488 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3489 /* Note that NV_TEXGEN_REFLECTION support is implied when
3490 * ARB_TEXTURE_CUBE_MAP is supported */
3491 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3493 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3494 break;
3497 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3498 gl_info->gl_ops.gl.p_glPushMatrix();
3499 gl_info->gl_ops.gl.p_glLoadIdentity();
3500 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3501 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3502 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3503 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3504 gl_info->gl_ops.gl.p_glPopMatrix();
3505 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3507 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3508 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3509 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3510 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3512 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3513 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3514 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3515 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3517 break;
3519 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3520 /* Note that NV_TEXGEN_REFLECTION support is implied when
3521 * ARB_TEXTURE_CUBE_MAP is supported */
3522 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3524 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3525 break;
3528 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3529 gl_info->gl_ops.gl.p_glPushMatrix();
3530 gl_info->gl_ops.gl.p_glLoadIdentity();
3531 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3532 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3533 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3534 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3535 gl_info->gl_ops.gl.p_glPopMatrix();
3536 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3538 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3539 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3540 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3541 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3543 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3544 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3545 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3546 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3548 break;
3550 case WINED3DTSS_TCI_SPHEREMAP:
3551 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3552 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3553 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3555 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3556 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3557 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3558 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3560 break;
3562 default:
3563 FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3564 state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3565 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3566 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3567 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3568 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3569 checkGLcall("Disable texgen.");
3571 break;
3574 /* Update the texture matrix. */
3575 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3576 transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3578 if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3580 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3581 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3582 * and do all the things linked to it
3583 * TODO: Tidy that up to reload only the arrays of the changed unit
3585 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3587 unload_tex_coords(gl_info);
3588 load_tex_coords(context, &device->stream_info, &curVBO, state);
3592 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3594 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3595 const struct wined3d_shader *ps = state->pixel_shader;
3597 /* The pixel shader has to know the luminance scale. Do a constants update. */
3598 if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3599 context->load_constants = 1;
3602 void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3604 const DWORD sampler = state_id - STATE_SAMPLER(0);
3605 const struct wined3d_texture *texture = state->textures[sampler];
3607 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3609 if(!texture) return;
3610 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3611 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3612 * scaling is reapplied or removed, the texture matrix has to be reapplied
3614 * The mapped stage is already active because the sampler() function below, which is part of the
3615 * misc pipeline
3617 if (sampler < MAX_TEXTURES)
3619 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3621 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3623 const struct wined3d_device *device = context->swapchain->device;
3625 if (texIsPow2)
3626 context->lastWasPow2Texture |= 1 << sampler;
3627 else
3628 context->lastWasPow2Texture &= ~(1 << sampler);
3630 transform_texture(context, state,
3631 STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3636 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3638 const struct wined3d_device *device = context->swapchain->device;
3639 DWORD sampler = state_id - STATE_SAMPLER(0);
3640 DWORD mapped_stage = device->texUnitMap[sampler];
3641 const struct wined3d_gl_info *gl_info = context->gl_info;
3642 union {
3643 float f;
3644 DWORD d;
3645 } tmpvalue;
3647 TRACE("Sampler: %d\n", sampler);
3648 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3649 * only has to bind textures and set the per texture states
3652 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3654 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3655 return;
3658 if (mapped_stage >= gl_info->limits.combined_samplers)
3660 return;
3662 context_active_texture(context, gl_info, mapped_stage);
3664 if (state->textures[sampler])
3666 struct wined3d_texture *texture = state->textures[sampler];
3667 BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3669 texture->texture_ops->texture_bind(texture, context, srgb);
3670 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3672 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3674 tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3675 gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3676 GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f);
3677 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3680 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3682 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3684 /* If color keying is enabled update the alpha test, it
3685 * depends on the existence of a color key in stage 0. */
3686 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3690 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3691 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3692 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3694 else
3696 if (sampler < state->lowest_disabled_stage)
3698 /* TODO: What should I do with pixel shaders here ??? */
3699 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3701 /* If color keying is enabled update the alpha test, it
3702 * depends on the existence of a color key in stage 0. */
3703 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3705 } /* Otherwise tex_colorop disables the stage */
3706 context_bind_texture(context, GL_NONE, 0);
3710 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3712 unsigned int i;
3714 if (use_ps(state))
3716 if (!context->last_was_pshader)
3718 /* Former draw without a pixel shader, some samplers may be
3719 * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3720 * make sure to enable them. */
3721 for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3723 if (!isStateDirty(context, STATE_SAMPLER(i)))
3724 sampler(context, state, STATE_SAMPLER(i));
3726 context->last_was_pshader = TRUE;
3728 else
3730 /* Otherwise all samplers were activated by the code above in
3731 * earlier draws, or by sampler() if a different texture was
3732 * bound. I don't have to do anything. */
3735 else
3737 /* Disabled the pixel shader - color ops weren't applied while it was
3738 * enabled, so re-apply them. */
3739 for (i = 0; i < context->d3d_info->limits.ffp_blend_stages; ++i)
3741 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3742 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3744 context->last_was_pshader = FALSE;
3747 context->select_shader = 1;
3748 context->load_constants = 1;
3751 static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3753 context->select_shader = 1;
3756 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3758 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3759 const struct wined3d_shader *ps = state->pixel_shader;
3761 /* The pixel shader has to know the bump env matrix. Do a constants update. */
3762 if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3763 context->load_constants = 1;
3766 void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3768 const struct wined3d_gl_info *gl_info = context->gl_info;
3770 /* This function is called by transform_view below if the view matrix was changed too
3772 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3773 * does not always update the world matrix, only on a switch between transformed
3774 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3775 * draw, but that should be rather rare and cheaper in total.
3777 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3778 checkGLcall("glMatrixMode");
3780 if (context->last_was_rhw)
3782 gl_info->gl_ops.gl.p_glLoadIdentity();
3783 checkGLcall("glLoadIdentity()");
3785 else
3787 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3788 checkGLcall("glLoadMatrixf");
3789 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3790 checkGLcall("glMultMatrixf");
3794 void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3796 const struct wined3d_gl_info *gl_info = context->gl_info;
3797 UINT index = state_id - STATE_CLIPPLANE(0);
3798 GLdouble plane[4];
3800 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.clipplanes)
3801 return;
3803 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3804 gl_info->gl_ops.gl.p_glPushMatrix();
3806 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3807 if (!use_vs(state))
3808 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3809 else
3810 /* With vertex shaders, clip planes are not transformed in Direct3D,
3811 * while in OpenGL they are still transformed by the model view matix. */
3812 gl_info->gl_ops.gl.p_glLoadIdentity();
3814 plane[0] = state->clip_planes[index].x;
3815 plane[1] = state->clip_planes[index].y;
3816 plane[2] = state->clip_planes[index].z;
3817 plane[3] = state->clip_planes[index].w;
3819 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3820 plane[0], plane[1], plane[2], plane[3]);
3821 gl_info->gl_ops.gl.p_glClipPlane(GL_CLIP_PLANE0 + index, plane);
3822 checkGLcall("glClipPlane");
3824 gl_info->gl_ops.gl.p_glPopMatrix();
3827 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3829 UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3830 const struct wined3d_gl_info *gl_info = context->gl_info;
3831 GLenum glMat;
3833 TRACE("Setting world matrix %d\n", matrix);
3835 if (matrix >= gl_info->limits.blends)
3837 WARN("Unsupported blend matrix set\n");
3838 return;
3841 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3842 return;
3844 /* GL_MODELVIEW0_ARB: 0x1700
3845 * GL_MODELVIEW1_ARB: 0x850a
3846 * GL_MODELVIEW2_ARB: 0x8722
3847 * GL_MODELVIEW3_ARB: 0x8723
3848 * etc
3849 * GL_MODELVIEW31_ARB: 0x873f
3851 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3852 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3854 gl_info->gl_ops.gl.p_glMatrixMode(glMat);
3855 checkGLcall("glMatrixMode(glMat)");
3857 /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3858 * matrices while gl uses only 2. To avoid weighting the view matrix
3859 * incorrectly it has to be multiplied into every GL modelview matrix. */
3860 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3861 checkGLcall("glLoadMatrixf");
3862 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3863 checkGLcall("glMultMatrixf");
3866 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3868 enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3869 static unsigned int once;
3871 if (f == WINED3D_VBF_DISABLE)
3872 return;
3874 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3875 else WARN("Vertex blend flags %#x not supported.\n", f);
3878 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3880 enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3881 struct wined3d_device *device = context->swapchain->device;
3882 const struct wined3d_gl_info *gl_info = context->gl_info;
3883 static unsigned int once;
3885 switch (val)
3887 case WINED3D_VBF_1WEIGHTS:
3888 case WINED3D_VBF_2WEIGHTS:
3889 case WINED3D_VBF_3WEIGHTS:
3890 gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB);
3891 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3893 /* D3D adds one more matrix which has weight (1 - sum(weights)).
3894 * This is enabled at context creation with enabling
3895 * GL_WEIGHT_SUM_UNITY_ARB. */
3896 GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3898 if (!device->vertexBlendUsed)
3900 unsigned int i;
3901 for (i = 1; i < gl_info->limits.blends; ++i)
3903 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3904 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3906 device->vertexBlendUsed = TRUE;
3908 break;
3910 case WINED3D_VBF_TWEENING:
3911 case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3912 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3913 else WARN("Vertex blend flags %#x not supported.\n", val);
3914 /* Fall through. */
3915 case WINED3D_VBF_DISABLE:
3916 gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB);
3917 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3918 break;
3922 void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3924 const struct wined3d_gl_info *gl_info = context->gl_info;
3925 const struct wined3d_light_info *light = NULL;
3926 unsigned int k;
3928 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3929 * NOTE: We have to reset the positions even if the light/plane is not currently
3930 * enabled, since the call to enable it will not reset the position.
3931 * NOTE2: Apparently texture transforms do NOT need reapplying
3934 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3935 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3936 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3937 checkGLcall("glLoadMatrixf(...)");
3939 /* Reset lights. TODO: Call light apply func */
3940 for (k = 0; k < gl_info->limits.lights; ++k)
3942 if (!(light = state->lights[k]))
3943 continue;
3944 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3945 checkGLcall("glLightfv posn");
3946 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3947 checkGLcall("glLightfv dirn");
3950 /* Reset Clipping Planes */
3951 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3953 if (!isStateDirty(context, STATE_CLIPPLANE(k)))
3954 clipplane(context, state, STATE_CLIPPLANE(k));
3957 if (context->last_was_rhw)
3959 gl_info->gl_ops.gl.p_glLoadIdentity();
3960 checkGLcall("glLoadIdentity()");
3961 /* No need to update the world matrix, the identity is fine */
3962 return;
3965 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3966 * No need to do it here if the state is scheduled for update. */
3967 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
3968 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
3970 /* Avoid looping over a number of matrices if the app never used the functionality */
3971 if (context->swapchain->device->vertexBlendUsed)
3973 for (k = 1; k < gl_info->limits.blends; ++k)
3975 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
3976 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
3981 void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3983 const struct wined3d_gl_info *gl_info = context->gl_info;
3985 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
3986 checkGLcall("glMatrixMode(GL_PROJECTION)");
3988 /* There are a couple of additional things we have to take into account
3989 * here besides the projection transformation itself:
3990 * - We need to flip along the y-axis in case of offscreen rendering.
3991 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
3992 * - D3D coordinates refer to pixel centers while GL coordinates refer
3993 * to pixel corners.
3994 * - D3D has a top-left filling convention. We need to maintain this
3995 * even after the y-flip mentioned above.
3996 * In order to handle the last two points, we translate by
3997 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
3998 * translating slightly less than half a pixel. We want the difference to
3999 * be large enough that it doesn't get lost due to rounding inside the
4000 * driver, but small enough to prevent it from interfering with any
4001 * anti-aliasing. */
4003 if (context->last_was_rhw)
4005 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
4006 double x = state->viewport.x;
4007 double y = state->viewport.y;
4008 double w = state->viewport.width;
4009 double h = state->viewport.height;
4010 double x_scale = 2.0 / w;
4011 double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
4012 double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
4013 double y_offset = context->render_offscreen
4014 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
4015 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
4016 const GLdouble projection[] =
4018 x_scale, 0.0, 0.0, 0.0,
4019 0.0, y_scale, 0.0, 0.0,
4020 0.0, 0.0, 2.0, 0.0,
4021 x_offset, y_offset, -1.0, 1.0,
4024 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4025 checkGLcall("glLoadMatrixd");
4027 else
4029 double y_scale = context->render_offscreen ? -1.0 : 1.0;
4030 double x_offset = (63.0 / 64.0) / state->viewport.width;
4031 double y_offset = context->render_offscreen
4032 ? (63.0 / 64.0) / state->viewport.height
4033 : -(63.0 / 64.0) / state->viewport.height;
4034 const GLdouble projection[] =
4036 1.0, 0.0, 0.0, 0.0,
4037 0.0, y_scale, 0.0, 0.0,
4038 0.0, 0.0, 2.0, 0.0,
4039 x_offset, y_offset, -1.0, 1.0,
4042 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4043 checkGLcall("glLoadMatrixd");
4045 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4046 checkGLcall("glLoadMatrixf");
4050 /* This should match any arrays loaded in load_vertex_data.
4051 * TODO: Only load / unload arrays if we have to. */
4052 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4054 gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
4055 gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
4056 gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
4057 if (gl_info->supported[EXT_SECONDARY_COLOR])
4058 gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4059 if (gl_info->supported[ARB_VERTEX_BLEND])
4060 gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4061 unload_tex_coords(gl_info);
4064 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4066 const struct wined3d_gl_info *gl_info = context->gl_info;
4068 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4069 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4070 if (gl_info->supported[ARB_INSTANCED_ARRAYS])
4071 GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
4073 context->numbered_array_mask &= ~(1 << i);
4076 /* This should match any arrays loaded in loadNumberedArrays
4077 * TODO: Only load / unload arrays if we have to. */
4078 static void unload_numbered_arrays(struct wined3d_context *context)
4080 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4081 int i;
4083 for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4084 unload_numbered_array(context, i);
4088 static void load_numbered_arrays(struct wined3d_context *context,
4089 const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4091 struct wined3d_device *device = context->swapchain->device;
4092 const struct wined3d_gl_info *gl_info = context->gl_info;
4093 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4094 int i;
4096 /* Default to no instancing */
4097 device->instance_count = 0;
4099 for (i = 0; i < MAX_ATTRIBS; i++)
4101 const struct wined3d_stream_state *stream;
4103 if (!(stream_info->use_map & (1 << i)))
4105 if (context->numbered_array_mask & (1 << i))
4106 unload_numbered_array(context, i);
4107 if (state->vertex_shader->reg_maps.input_registers & (1 << i))
4108 GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
4109 continue;
4112 stream = &state->streams[stream_info->elements[i].stream_idx];
4114 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4116 if (!device->instance_count)
4117 device->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
4119 if (!gl_info->supported[ARB_INSTANCED_ARRAYS])
4121 /* Unload instanced arrays, they will be loaded using
4122 * immediate mode instead. */
4123 if (context->numbered_array_mask & (1 << i))
4124 unload_numbered_array(context, i);
4125 continue;
4128 GL_EXTCALL(glVertexAttribDivisorARB(i, 1));
4130 else if (gl_info->supported[ARB_INSTANCED_ARRAYS])
4132 GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
4135 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4137 if (stream_info->elements[i].stride)
4139 if (curVBO != stream_info->elements[i].data.buffer_object)
4141 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4142 checkGLcall("glBindBufferARB");
4143 curVBO = stream_info->elements[i].data.buffer_object;
4145 /* Use the VBO to find out if a vertex buffer exists, not the vb
4146 * pointer. vb can point to a user pointer data blob. In that case
4147 * curVBO will be 0. If there is a vertex buffer but no vbo we
4148 * won't be load converted attributes anyway. */
4149 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4150 stream_info->elements[i].format->gl_vtx_type,
4151 stream_info->elements[i].format->gl_normalized,
4152 stream_info->elements[i].stride, stream_info->elements[i].data.addr
4153 + state->load_base_vertex_index * stream_info->elements[i].stride));
4155 if (!(context->numbered_array_mask & (1 << i)))
4157 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4158 context->numbered_array_mask |= (1 << i);
4161 else
4163 /* Stride = 0 means always the same values.
4164 * glVertexAttribPointerARB doesn't do that. Instead disable the
4165 * pointer and set up the attribute statically. But we have to
4166 * figure out the system memory address. */
4167 const BYTE *ptr = stream_info->elements[i].data.addr;
4168 if (stream_info->elements[i].data.buffer_object)
4170 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4173 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4175 switch (stream_info->elements[i].format->id)
4177 case WINED3DFMT_R32_FLOAT:
4178 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4179 break;
4180 case WINED3DFMT_R32G32_FLOAT:
4181 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4182 break;
4183 case WINED3DFMT_R32G32B32_FLOAT:
4184 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4185 break;
4186 case WINED3DFMT_R32G32B32A32_FLOAT:
4187 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4188 break;
4190 case WINED3DFMT_R8G8B8A8_UINT:
4191 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4192 break;
4193 case WINED3DFMT_B8G8R8A8_UNORM:
4194 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4196 const DWORD *src = (const DWORD *)ptr;
4197 DWORD c = *src & 0xff00ff00;
4198 c |= (*src & 0xff0000) >> 16;
4199 c |= (*src & 0xff) << 16;
4200 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4201 break;
4203 /* else fallthrough */
4204 case WINED3DFMT_R8G8B8A8_UNORM:
4205 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4206 break;
4208 case WINED3DFMT_R16G16_SINT:
4209 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4210 break;
4211 case WINED3DFMT_R16G16B16A16_SINT:
4212 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4213 break;
4215 case WINED3DFMT_R16G16_SNORM:
4217 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4218 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4219 break;
4221 case WINED3DFMT_R16G16_UNORM:
4223 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4224 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4225 break;
4227 case WINED3DFMT_R16G16B16A16_SNORM:
4228 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4229 break;
4230 case WINED3DFMT_R16G16B16A16_UNORM:
4231 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4232 break;
4234 case WINED3DFMT_R10G10B10A2_UINT:
4235 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4236 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4237 break;
4238 case WINED3DFMT_R10G10B10A2_SNORM:
4239 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4240 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4241 break;
4243 case WINED3DFMT_R16G16_FLOAT:
4244 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4245 * byte float according to the IEEE standard
4247 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4248 break;
4249 case WINED3DFMT_R16G16B16A16_FLOAT:
4250 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4251 break;
4253 default:
4254 ERR("Unexpected declaration in stride 0 attributes\n");
4255 break;
4260 checkGLcall("Loading numbered arrays");
4263 static void load_vertex_data(const struct wined3d_context *context,
4264 const struct wined3d_stream_info *si, const struct wined3d_state *state)
4266 struct wined3d_device *device = context->swapchain->device;
4267 const struct wined3d_gl_info *gl_info = context->gl_info;
4268 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4269 const struct wined3d_stream_info_element *e;
4271 TRACE("Using fast vertex array code\n");
4273 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4274 device->instance_count = 0;
4276 /* Blend Data ---------------------------------------------- */
4277 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4278 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4280 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4282 if (gl_info->supported[ARB_VERTEX_BLEND])
4284 TRACE("Blend %u %p %u\n", e->format->component_count,
4285 e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4287 gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4288 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4290 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4292 if (curVBO != e->data.buffer_object)
4294 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4295 checkGLcall("glBindBufferARB");
4296 curVBO = e->data.buffer_object;
4299 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4300 e->format->gl_vtx_format,
4301 e->format->gl_vtx_type,
4302 e->stride,
4303 e->data.addr + state->load_base_vertex_index * e->stride);
4304 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4305 e->data.addr + state->load_base_vertex_index * e->stride));
4307 checkGLcall("glWeightPointerARB");
4309 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4311 static BOOL warned;
4312 if (!warned)
4314 FIXME("blendMatrixIndices support\n");
4315 warned = TRUE;
4318 } else {
4319 /* TODO: support blends in drawStridedSlow
4320 * No need to write a FIXME here, this is done after the general vertex decl decoding
4322 WARN("unsupported blending in openGl\n");
4325 else
4327 if (gl_info->supported[ARB_VERTEX_BLEND])
4329 static const GLbyte one = 1;
4330 GL_EXTCALL(glWeightbvARB(1, &one));
4331 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4335 /* Point Size ----------------------------------------------*/
4336 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4338 /* no such functionality in the fixed function GL pipeline */
4339 TRACE("Cannot change ptSize here in openGl\n");
4340 /* TODO: Implement this function in using shaders if they are available */
4343 /* Vertex Pointers -----------------------------------------*/
4344 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4346 e = &si->elements[WINED3D_FFP_POSITION];
4348 if (curVBO != e->data.buffer_object)
4350 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4351 checkGLcall("glBindBufferARB");
4352 curVBO = e->data.buffer_object;
4355 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4356 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4357 e->data.addr + state->load_base_vertex_index * e->stride);
4358 gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4359 e->data.addr + state->load_base_vertex_index * e->stride);
4360 checkGLcall("glVertexPointer(...)");
4361 gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
4362 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4365 /* Normals -------------------------------------------------*/
4366 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4368 e = &si->elements[WINED3D_FFP_NORMAL];
4370 if (curVBO != e->data.buffer_object)
4372 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4373 checkGLcall("glBindBufferARB");
4374 curVBO = e->data.buffer_object;
4377 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4378 e->data.addr + state->load_base_vertex_index * e->stride);
4379 gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
4380 e->data.addr + state->load_base_vertex_index * e->stride);
4381 checkGLcall("glNormalPointer(...)");
4382 gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
4383 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4386 else
4388 gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
4389 checkGLcall("glNormal3f(0, 0, 0)");
4392 /* Diffuse Colour --------------------------------------------*/
4393 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4395 e = &si->elements[WINED3D_FFP_DIFFUSE];
4397 if (curVBO != e->data.buffer_object)
4399 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4400 checkGLcall("glBindBufferARB");
4401 curVBO = e->data.buffer_object;
4404 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4405 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4406 e->data.addr + state->load_base_vertex_index * e->stride);
4407 gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4408 e->data.addr + state->load_base_vertex_index * e->stride);
4409 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4410 gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
4411 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4414 else
4416 gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4417 checkGLcall("glColor4f(1, 1, 1, 1)");
4420 /* Specular Colour ------------------------------------------*/
4421 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4423 TRACE("setting specular colour\n");
4425 e = &si->elements[WINED3D_FFP_SPECULAR];
4427 if (gl_info->supported[EXT_SECONDARY_COLOR])
4429 GLenum type = e->format->gl_vtx_type;
4430 GLint format = e->format->gl_vtx_format;
4432 if (curVBO != e->data.buffer_object)
4434 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4435 checkGLcall("glBindBufferARB");
4436 curVBO = e->data.buffer_object;
4439 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4441 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4442 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4443 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4444 * 4 component secondary colors use it
4446 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4447 e->data.addr + state->load_base_vertex_index * e->stride);
4448 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4449 e->data.addr + state->load_base_vertex_index * e->stride));
4450 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4452 else
4454 switch(type)
4456 case GL_UNSIGNED_BYTE:
4457 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4458 e->data.addr + state->load_base_vertex_index * e->stride);
4459 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4460 e->data.addr + state->load_base_vertex_index * e->stride));
4461 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4462 break;
4464 default:
4465 FIXME("Add 4 component specular color pointers for type %x\n", type);
4466 /* Make sure that the right color component is dropped */
4467 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4468 e->data.addr + state->load_base_vertex_index * e->stride);
4469 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4470 e->data.addr + state->load_base_vertex_index * e->stride));
4471 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4474 gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4475 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4477 else
4479 WARN("Specular colour is not supported in this GL implementation.\n");
4482 else
4484 if (gl_info->supported[EXT_SECONDARY_COLOR])
4486 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4487 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4489 else
4491 WARN("Specular colour is not supported in this GL implementation.\n");
4495 /* Texture coords -------------------------------------------*/
4496 load_tex_coords(context, si, &curVBO, state);
4499 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4501 const struct wined3d_device *device = context->swapchain->device;
4502 BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4503 BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4505 if (isStateDirty(context, STATE_VDECL)) return;
4506 if (context->numberedArraysLoaded && !load_numbered)
4508 unload_numbered_arrays(context);
4509 context->numberedArraysLoaded = FALSE;
4510 context->numbered_array_mask = 0;
4512 else if (context->namedArraysLoaded)
4514 unload_vertex_data(context->gl_info);
4515 context->namedArraysLoaded = FALSE;
4518 if (load_numbered)
4520 TRACE("Loading numbered arrays\n");
4521 load_numbered_arrays(context, &device->stream_info, state);
4522 context->numberedArraysLoaded = TRUE;
4524 else if (load_named)
4526 TRACE("Loading vertex data\n");
4527 load_vertex_data(context, &device->stream_info, state);
4528 context->namedArraysLoaded = TRUE;
4532 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4534 if (isStateDirty(context, STATE_STREAMSRC))
4535 return;
4536 streamsrc(context, state, STATE_STREAMSRC);
4539 void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4541 const struct wined3d_device *device = context->swapchain->device;
4542 const struct wined3d_gl_info *gl_info = context->gl_info;
4543 BOOL useVertexShaderFunction = use_vs(state);
4544 BOOL updateFog = FALSE;
4545 BOOL transformed;
4546 BOOL wasrhw = context->last_was_rhw;
4547 unsigned int i;
4549 transformed = device->stream_info.position_transformed;
4550 if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4551 updateFog = TRUE;
4553 context->last_was_rhw = transformed;
4555 /* Don't have to apply the matrices when vertex shaders are used. When
4556 * vshaders are turned off this function will be called again anyway to
4557 * make sure they're properly set. */
4558 if (!useVertexShaderFunction)
4560 /* TODO: Move this mainly to the viewport state and only apply when
4561 * the vp has changed or transformed / untransformed was switched. */
4562 if (wasrhw != context->last_was_rhw
4563 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4564 && !isStateDirty(context, STATE_VIEWPORT))
4565 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4566 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4567 * mode.
4569 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4570 * this check will fail and the matrix not applied again. This is OK because a simple
4571 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4572 * needs of the vertex declaration.
4574 * World and view matrix go into the same gl matrix, so only apply them when neither is
4575 * dirty
4577 if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4578 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4579 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4580 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4581 state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4582 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4583 state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4585 if (context->last_was_vshader)
4587 updateFog = TRUE;
4589 if (!context->d3d_info->vs_clipping
4590 && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4592 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4595 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4597 clipplane(context, state, STATE_CLIPPLANE(i));
4600 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4601 state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4603 else
4605 if(!context->last_was_vshader) {
4606 static BOOL warned = FALSE;
4607 if (!context->d3d_info->vs_clipping)
4609 /* Disable all clip planes to get defined results on all drivers. See comment in the
4610 * state_clipping state handler
4612 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4614 gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i);
4615 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4618 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4620 FIXME("Clipping not supported with vertex shaders\n");
4621 warned = TRUE;
4624 if (wasrhw)
4626 /* Apply the transform matrices when switching from rhw
4627 * drawing to vertex shaders. Vertex shaders themselves do
4628 * not need it, but the matrices are not reapplied
4629 * automatically when switching back from vertex shaders to
4630 * fixed function processing. So make sure we leave the fixed
4631 * function vertex processing states back in a sane state
4632 * before switching to shaders. */
4633 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4634 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4635 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4636 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4638 updateFog = TRUE;
4640 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4641 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4642 * device->vs_clipping is false.
4644 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4646 clipplane(context, state, STATE_CLIPPLANE(i));
4651 context->last_was_vshader = useVertexShaderFunction;
4652 context->select_shader = 1;
4653 context->load_constants = 1;
4655 if (updateFog)
4656 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4658 if (!useVertexShaderFunction)
4660 unsigned int i;
4662 for (i = 0; i < MAX_TEXTURES; ++i)
4664 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4665 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4669 if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4670 state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4673 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4675 const struct wined3d_surface *target = state->fb->render_targets[0];
4676 const struct wined3d_gl_info *gl_info = context->gl_info;
4677 struct wined3d_viewport vp = state->viewport;
4679 if (vp.width > target->resource.width)
4680 vp.width = target->resource.width;
4681 if (vp.height > target->resource.height)
4682 vp.height = target->resource.height;
4684 gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
4685 checkGLcall("glDepthRange");
4686 /* Note: GL requires lower left, DirectX supplies upper left. This is
4687 * reversed when using offscreen rendering. */
4688 if (context->render_offscreen)
4690 gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
4692 else
4694 UINT width, height;
4696 target->get_drawable_size(context, &width, &height);
4697 gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)),
4698 vp.width, vp.height);
4701 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4702 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4704 checkGLcall("glViewport");
4707 void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4709 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4710 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4711 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4712 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4713 /* Update the position fixup. */
4714 context->load_constants = 1;
4717 void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4719 const struct wined3d_gl_info *gl_info = context->gl_info;
4720 UINT Index = state_id - STATE_ACTIVELIGHT(0);
4721 const struct wined3d_light_info *lightInfo = state->lights[Index];
4723 if (!lightInfo)
4725 gl_info->gl_ops.gl.p_glDisable(GL_LIGHT0 + Index);
4726 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4728 else
4730 float quad_att;
4731 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4733 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4734 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
4735 gl_info->gl_ops.gl.p_glPushMatrix();
4736 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4738 /* Diffuse: */
4739 colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4740 colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4741 colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4742 colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4743 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4744 checkGLcall("glLightfv");
4746 /* Specular */
4747 colRGBA[0] = lightInfo->OriginalParms.specular.r;
4748 colRGBA[1] = lightInfo->OriginalParms.specular.g;
4749 colRGBA[2] = lightInfo->OriginalParms.specular.b;
4750 colRGBA[3] = lightInfo->OriginalParms.specular.a;
4751 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4752 checkGLcall("glLightfv");
4754 /* Ambient */
4755 colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4756 colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4757 colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4758 colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4759 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4760 checkGLcall("glLightfv");
4762 if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4763 quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4764 else
4765 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4767 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4768 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4769 * Attenuation0 to NaN and crashes in the gl lib
4772 switch (lightInfo->OriginalParms.type)
4774 case WINED3D_LIGHT_POINT:
4775 /* Position */
4776 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4777 checkGLcall("glLightfv");
4778 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4779 checkGLcall("glLightf");
4780 /* Attenuation - Are these right? guessing... */
4781 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4782 lightInfo->OriginalParms.attenuation0);
4783 checkGLcall("glLightf");
4784 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4785 lightInfo->OriginalParms.attenuation1);
4786 checkGLcall("glLightf");
4787 if (quad_att < lightInfo->OriginalParms.attenuation2)
4788 quad_att = lightInfo->OriginalParms.attenuation2;
4789 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4790 checkGLcall("glLightf");
4791 /* FIXME: Range */
4792 break;
4794 case WINED3D_LIGHT_SPOT:
4795 /* Position */
4796 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4797 checkGLcall("glLightfv");
4798 /* Direction */
4799 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4800 checkGLcall("glLightfv");
4801 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4802 checkGLcall("glLightf");
4803 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4804 checkGLcall("glLightf");
4805 /* Attenuation - Are these right? guessing... */
4806 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4807 lightInfo->OriginalParms.attenuation0);
4808 checkGLcall("glLightf");
4809 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4810 lightInfo->OriginalParms.attenuation1);
4811 checkGLcall("glLightf");
4812 if (quad_att < lightInfo->OriginalParms.attenuation2)
4813 quad_att = lightInfo->OriginalParms.attenuation2;
4814 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4815 checkGLcall("glLightf");
4816 /* FIXME: Range */
4817 break;
4819 case WINED3D_LIGHT_DIRECTIONAL:
4820 /* Direction */
4821 /* Note GL uses w position of 0 for direction! */
4822 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4823 checkGLcall("glLightfv");
4824 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4825 checkGLcall("glLightf");
4826 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4827 checkGLcall("glLightf");
4828 break;
4830 default:
4831 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4834 /* Restore the modelview matrix */
4835 gl_info->gl_ops.gl.p_glPopMatrix();
4837 gl_info->gl_ops.gl.p_glEnable(GL_LIGHT0 + Index);
4838 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4842 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4844 const struct wined3d_gl_info *gl_info = context->gl_info;
4845 const RECT *r = &state->scissor_rect;
4847 /* Warning: glScissor uses window coordinates, not viewport coordinates,
4848 * so our viewport correction does not apply. Warning2: Even in windowed
4849 * mode the coords are relative to the window, not the screen. */
4850 TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4852 if (context->render_offscreen)
4854 gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4856 else
4858 const struct wined3d_surface *target = state->fb->render_targets[0];
4859 UINT height;
4860 UINT width;
4862 target->get_drawable_size(context, &width, &height);
4863 gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4865 checkGLcall("glScissor");
4868 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4870 const struct wined3d_stream_info *stream_info = &context->swapchain->device->stream_info;
4871 const struct wined3d_gl_info *gl_info = context->gl_info;
4873 if (!state->index_buffer || !stream_info->all_vbo)
4875 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4877 else
4879 struct wined3d_buffer *ib = state->index_buffer;
4880 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4884 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4886 const struct wined3d_gl_info *gl_info = context->gl_info;
4888 if (context->render_offscreen)
4890 gl_info->gl_ops.gl.p_glFrontFace(GL_CCW);
4891 checkGLcall("glFrontFace(GL_CCW)");
4893 else
4895 gl_info->gl_ops.gl.p_glFrontFace(GL_CW);
4896 checkGLcall("glFrontFace(GL_CW)");
4900 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4902 static BOOL warned;
4904 if (!warned)
4906 WARN("Point sprite coordinate origin switching not supported.\n");
4907 warned = TRUE;
4911 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4913 const struct wined3d_gl_info *gl_info = context->gl_info;
4914 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4916 if (gl_info->supported[NV_POINT_SPRITE])
4918 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4919 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4923 void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4925 const struct wined3d_gl_info *gl_info = context->gl_info;
4926 const struct wined3d_surface *rt = state->fb->render_targets[0];
4928 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
4930 if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
4931 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
4932 gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
4933 else
4934 gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
4937 const struct StateEntryTemplate misc_state_template[] = {
4938 { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4939 { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4940 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4941 { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4942 { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4943 { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4944 { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4945 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4946 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4947 { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4948 { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
4949 { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
4950 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4951 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4952 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4953 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4955 /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4956 * vshader loadings are untied from each other
4958 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4959 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4960 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4961 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4962 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4963 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4964 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4965 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4966 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4967 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4968 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4969 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4970 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4971 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4972 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4973 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4974 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4975 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4976 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4977 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4978 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4979 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4980 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4981 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4982 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4983 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4984 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4985 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4986 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4987 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4988 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4989 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4990 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4991 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4992 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4993 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4994 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4995 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4996 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4997 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4998 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4999 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5000 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5001 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5003 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5004 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5005 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5006 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5007 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5009 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
5010 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
5011 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
5012 { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
5013 { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
5014 { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
5015 { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
5016 { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
5017 { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
5018 { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
5019 { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
5020 { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
5021 { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
5022 { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
5023 { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
5024 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
5025 { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5026 { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5027 { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5028 { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
5029 { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
5030 { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
5031 { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
5032 { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
5033 { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
5034 { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
5035 { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
5036 { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
5037 { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
5038 { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
5039 { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
5040 { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5042 { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5044 { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5045 { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5046 { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5047 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
5048 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5050 { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5051 { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5052 { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5053 { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5054 { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5055 { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5056 { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5057 { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5058 { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5059 { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5060 { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5061 { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5062 { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5063 { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5064 { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5065 { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5066 { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5067 { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5068 { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5069 { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5070 { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5071 { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5072 { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5073 { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5074 { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5075 { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5076 { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5077 { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5078 { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5079 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5080 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5081 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5082 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5083 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5084 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
5085 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5086 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5087 { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5088 { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5089 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5090 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5091 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5092 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5093 { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5094 { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5095 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5096 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5097 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5098 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5099 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5100 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5101 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5102 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5103 { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5104 { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5105 /* Samplers */
5106 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5107 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5108 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5109 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5110 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5111 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5112 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5113 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5114 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5115 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5116 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5117 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5118 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5119 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5120 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5121 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5122 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5123 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5124 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5125 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5126 { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
5127 { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
5128 { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
5129 { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
5130 { STATE_GEOMETRY_SHADER, { STATE_GEOMETRY_SHADER, state_geometry_shader}, WINED3D_GL_EXT_NONE },
5131 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5134 const struct StateEntryTemplate vp_ffp_states[] =
5136 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5137 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5138 { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5139 { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5140 /* Clip planes */
5141 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5142 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5143 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5144 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5145 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5146 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5147 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5148 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5149 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5150 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5151 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5152 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5153 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5154 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5155 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5156 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5157 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5158 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5159 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5160 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5161 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5162 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5163 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5164 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5165 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5166 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5167 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5168 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5169 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5170 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5171 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5172 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5173 /* Lights */
5174 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5175 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5176 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5177 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5178 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5179 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5180 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5181 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5182 /* Viewport */
5183 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5184 /* Transform states follow */
5185 { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5186 { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5187 { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5188 { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5189 { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5190 { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5191 { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5192 { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5193 { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5194 { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5195 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5396 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5397 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5400 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5401 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5402 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5403 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5405 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5406 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5407 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5411 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5412 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5413 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5414 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5415 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5416 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5417 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5418 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5419 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5420 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5421 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5422 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5423 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5424 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5425 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5426 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5427 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5428 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5429 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5430 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5431 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5432 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5433 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5434 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5435 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5436 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5437 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5438 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5439 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5440 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5441 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5442 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5443 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5444 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5445 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5446 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5447 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5448 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5449 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5450 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5451 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5452 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5453 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5454 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5455 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5456 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5457 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5458 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5459 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5460 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5461 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5462 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5463 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5464 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5465 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5466 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5467 /* Fog */
5468 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5469 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5470 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5471 { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5472 { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5473 { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5474 { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5475 { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5476 { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5477 { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5478 { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5479 { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5480 { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5481 { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5482 { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5483 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5484 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5485 { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5486 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5487 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5488 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5489 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5490 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5491 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5492 { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5493 { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5494 { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5495 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5496 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5497 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5498 { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5499 { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5501 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5502 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5503 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5505 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5506 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5507 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5508 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5509 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5510 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5511 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5512 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5513 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5514 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5515 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5516 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5517 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5518 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5519 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5520 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5521 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5522 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5523 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5524 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5525 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5526 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5527 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5528 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5529 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5532 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5533 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5534 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5535 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5536 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5537 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5538 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5539 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5540 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5541 { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5542 { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5543 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5544 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5545 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5546 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5547 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5548 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5549 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5550 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5551 { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5552 { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5553 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5554 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5555 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5556 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5557 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5558 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5559 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5560 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5561 { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5562 { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5563 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5564 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5565 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5566 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5567 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5568 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5569 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5570 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5571 { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5572 { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5573 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5574 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5575 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5576 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5577 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5578 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5579 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5580 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5581 { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5582 { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5583 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5584 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5585 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5586 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5587 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5588 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5589 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5590 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5591 { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5592 { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5593 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5594 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5595 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5596 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5597 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5598 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5599 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5600 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5601 { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5602 { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5603 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5604 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5605 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5606 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5607 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5608 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5609 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5610 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5611 { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5612 { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5613 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5614 { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5615 { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5616 { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5617 { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5618 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5619 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5620 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5621 { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5622 { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5623 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5624 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5625 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5626 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5627 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5628 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5629 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5630 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5631 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5634 /* Context activation is done by the caller. */
5635 static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5637 static void *ffp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
5639 return shader_priv;
5642 static void ffp_free(struct wined3d_device *device) {}
5644 static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
5646 caps->max_active_lights = gl_info->limits.lights;
5647 caps->max_vertex_blend_matrices = gl_info->limits.blends;
5648 caps->max_vertex_blend_matrix_index = 0;
5649 caps->vertex_processing_caps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS
5650 | WINED3DVTXPCAPS_MATERIALSOURCE7
5651 | WINED3DVTXPCAPS_POSITIONALLIGHTS
5652 | WINED3DVTXPCAPS_LOCALVIEWER
5653 | WINED3DVTXPCAPS_VERTEXFOG
5654 | WINED3DVTXPCAPS_TEXGEN
5655 | WINED3DVTXPCAPS_TEXGEN_SPHEREMAP;
5656 caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
5657 caps->max_user_clip_planes = gl_info->limits.clipplanes;
5658 caps->raster_caps = 0;
5659 if (gl_info->supported[NV_FOG_DISTANCE])
5660 caps->raster_caps |= WINED3DPRASTERCAPS_FOGRANGE;
5663 const struct wined3d_vertex_pipe_ops ffp_vertex_pipe =
5665 ffp_enable,
5666 vp_ffp_get_caps,
5667 ffp_alloc,
5668 ffp_free,
5669 vp_ffp_states,
5672 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5674 caps->wined3d_caps = 0;
5675 caps->PrimitiveMiscCaps = 0;
5676 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5677 | WINED3DTEXOPCAPS_ADDSIGNED
5678 | WINED3DTEXOPCAPS_ADDSIGNED2X
5679 | WINED3DTEXOPCAPS_MODULATE
5680 | WINED3DTEXOPCAPS_MODULATE2X
5681 | WINED3DTEXOPCAPS_MODULATE4X
5682 | WINED3DTEXOPCAPS_SELECTARG1
5683 | WINED3DTEXOPCAPS_SELECTARG2
5684 | WINED3DTEXOPCAPS_DISABLE;
5686 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5687 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5688 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5690 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5691 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5692 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5693 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5694 | WINED3DTEXOPCAPS_LERP
5695 | WINED3DTEXOPCAPS_SUBTRACT;
5697 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5698 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5700 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5701 | WINED3DTEXOPCAPS_MULTIPLYADD
5702 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5703 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5704 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5706 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5707 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5709 caps->MaxTextureBlendStages = gl_info->limits.textures;
5710 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5713 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5715 if (TRACE_ON(d3d))
5717 TRACE("Checking support for fixup:\n");
5718 dump_color_fixup_desc(fixup);
5721 /* We only support identity conversions. */
5722 if (is_identity_fixup(fixup))
5724 TRACE("[OK]\n");
5725 return TRUE;
5728 TRACE("[FAILED]\n");
5729 return FALSE;
5732 const struct fragment_pipeline ffp_fragment_pipeline = {
5733 ffp_enable,
5734 ffp_fragment_get_caps,
5735 ffp_alloc,
5736 ffp_free,
5737 ffp_color_fixup_supported,
5738 ffp_fragmentstate_template,
5741 static void none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5743 static void *none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
5745 return shader_priv;
5748 static void none_free(struct wined3d_device *device) {}
5750 static void vp_none_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
5752 memset(caps, 0, sizeof(*caps));
5755 const struct wined3d_vertex_pipe_ops none_vertex_pipe =
5757 none_enable,
5758 vp_none_get_caps,
5759 none_alloc,
5760 none_free,
5761 NULL,
5764 static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5766 memset(caps, 0, sizeof(*caps));
5769 static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
5771 return is_identity_fixup(fixup);
5774 const struct fragment_pipeline none_fragment_pipe =
5776 none_enable,
5777 fp_none_get_caps,
5778 none_alloc,
5779 none_free,
5780 fp_none_color_fixup_supported,
5781 NULL,
5784 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5786 unsigned int i;
5787 for(i = 0; funcs[i]; i++);
5788 return i;
5791 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5793 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5794 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5797 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5799 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5800 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5801 context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5804 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info,
5805 const struct wined3d_d3d_info *d3d_info)
5807 unsigned int start, last, i;
5809 start = STATE_TEXTURESTAGE(d3d_info->limits.ffp_blend_stages, 0);
5810 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5811 for (i = start; i <= last; ++i)
5813 state_table[i].representative = 0;
5814 state_table[i].apply = state_undefined;
5817 start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + d3d_info->limits.ffp_blend_stages);
5818 last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5819 for (i = start; i <= last; ++i)
5821 state_table[i].representative = 0;
5822 state_table[i].apply = state_undefined;
5825 start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5826 last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5827 for (i = start; i <= last; ++i)
5829 state_table[i].representative = 0;
5830 state_table[i].apply = state_undefined;
5834 static void validate_state_table(struct StateEntry *state_table)
5836 static const struct
5838 DWORD first;
5839 DWORD last;
5841 rs_holes[] =
5843 { 1, 1},
5844 { 3, 3},
5845 { 17, 18},
5846 { 21, 21},
5847 { 42, 45},
5848 { 47, 47},
5849 { 61, 127},
5850 {149, 150},
5851 {169, 169},
5852 {177, 177},
5853 {196, 197},
5854 { 0, 0},
5856 static const DWORD simple_states[] =
5858 STATE_MATERIAL,
5859 STATE_VDECL,
5860 STATE_STREAMSRC,
5861 STATE_INDEXBUFFER,
5862 STATE_VERTEXSHADERCONSTANT,
5863 STATE_PIXELSHADERCONSTANT,
5864 STATE_VSHADER,
5865 STATE_GEOMETRY_SHADER,
5866 STATE_PIXELSHADER,
5867 STATE_VIEWPORT,
5868 STATE_SCISSORRECT,
5869 STATE_FRONTFACE,
5870 STATE_POINTSPRITECOORDORIGIN,
5871 STATE_BASEVERTEXINDEX,
5872 STATE_FRAMEBUFFER
5874 unsigned int i, current;
5876 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5878 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5880 if (!state_table[i].representative)
5881 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5883 else if (state_table[i].representative)
5884 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5886 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5889 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5891 if (!state_table[simple_states[i]].representative)
5892 ERR("State %s (%#x) should have a representative.\n",
5893 debug_d3dstate(simple_states[i]), simple_states[i]);
5896 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5898 DWORD rep = state_table[i].representative;
5899 if (rep)
5901 if (state_table[rep].representative != rep)
5903 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5904 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5905 state_table[i].representative = 0;
5908 if (rep != i)
5910 if (state_table[i].apply)
5911 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5913 else if (!state_table[i].apply)
5915 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5921 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5922 const struct wined3d_gl_info *gl_info, const struct wined3d_d3d_info *d3d_info,
5923 const struct wined3d_vertex_pipe_ops *vertex, const struct fragment_pipeline *fragment,
5924 const struct StateEntryTemplate *misc)
5926 unsigned int i, type, handlers;
5927 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5928 const struct StateEntryTemplate *cur;
5929 BOOL set[STATE_HIGHEST + 1];
5931 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5933 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5934 StateTable[i].representative = 0;
5935 StateTable[i].apply = state_undefined;
5938 for(type = 0; type < 3; type++) {
5939 /* This switch decides the order in which the states are applied */
5940 switch(type) {
5941 case 0: cur = misc; break;
5942 case 1: cur = fragment->states; break;
5943 case 2: cur = vertex->vp_states; break;
5944 default: cur = NULL; /* Stupid compiler */
5946 if(!cur) continue;
5948 /* GL extension filtering should not prevent multiple handlers being applied from different
5949 * pipeline parts
5951 memset(set, 0, sizeof(set));
5953 for(i = 0; cur[i].state; i++) {
5954 APPLYSTATEFUNC *funcs_array;
5956 /* Only use the first matching state with the available extension from one template.
5957 * e.g.
5958 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5959 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5961 * if GL_XYZ_fancy is supported, ignore the 2nd line
5963 if(set[cur[i].state]) continue;
5964 /* Skip state lines depending on unsupported extensions */
5965 if (!gl_info->supported[cur[i].extension]) continue;
5966 set[cur[i].state] = TRUE;
5967 /* In some cases having an extension means that nothing has to be
5968 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5969 * supported, the texture coordinate fixup can be ignored. If the
5970 * apply function is used, mark the state set(done above) to prevent
5971 * applying later lines, but do not record anything in the state
5972 * table
5974 if (!cur[i].content.representative) continue;
5976 handlers = num_handlers(multistate_funcs[cur[i].state]);
5977 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5978 switch(handlers) {
5979 case 0:
5980 StateTable[cur[i].state].apply = cur[i].content.apply;
5981 break;
5982 case 1:
5983 StateTable[cur[i].state].apply = multistate_apply_2;
5984 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5986 sizeof(**dev_multistate_funcs) * 2);
5987 if (!dev_multistate_funcs[cur[i].state]) {
5988 goto out_of_mem;
5991 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5992 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5993 break;
5994 case 2:
5995 StateTable[cur[i].state].apply = multistate_apply_3;
5996 funcs_array = HeapReAlloc(GetProcessHeap(),
5998 dev_multistate_funcs[cur[i].state],
5999 sizeof(**dev_multistate_funcs) * 3);
6000 if (!funcs_array) {
6001 goto out_of_mem;
6004 dev_multistate_funcs[cur[i].state] = funcs_array;
6005 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
6006 break;
6007 default:
6008 ERR("Unexpected amount of state handlers for state %u: %u\n",
6009 cur[i].state, handlers + 1);
6012 if (StateTable[cur[i].state].representative
6013 && StateTable[cur[i].state].representative != cur[i].content.representative)
6015 FIXME("State %s (%#x) has different representatives in different pipeline parts.\n",
6016 debug_d3dstate(cur[i].state), cur[i].state);
6018 StateTable[cur[i].state].representative = cur[i].content.representative;
6022 prune_invalid_states(StateTable, gl_info, d3d_info);
6023 validate_state_table(StateTable);
6025 return WINED3D_OK;
6027 out_of_mem:
6028 for (i = 0; i <= STATE_HIGHEST; ++i) {
6029 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
6032 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
6034 return E_OUTOFMEMORY;