appwiz.cpl: Only offer to download an addon if its installer is missing.
[wine/multimedia.git] / dlls / wined3d / state.c
blobb3d5fa331874d1c37e24bb3565089f99fd34642e
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 /* GL locking for state handlers 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];
57 switch (mode)
59 case WINED3D_FILL_POINT:
60 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
61 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
62 break;
63 case WINED3D_FILL_WIREFRAME:
64 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
65 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
66 break;
67 case WINED3D_FILL_SOLID:
68 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
69 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
70 break;
71 default:
72 FIXME("Unrecognized fill mode %#x.\n", mode);
76 static void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
78 /* Lighting is not enabled if transformed vertices are drawn, but lighting
79 * does not affect the stream sources, so it is not grouped for
80 * performance reasons. This state reads the decoded vertex declaration,
81 * so if it is dirty don't do anything. The vertex declaration applying
82 * function calls this function for updating. */
83 if (isStateDirty(context, STATE_VDECL))
84 return;
86 if (state->render_states[WINED3D_RS_LIGHTING]
87 && !context->swapchain->device->strided_streams.position_transformed)
89 glEnable(GL_LIGHTING);
90 checkGLcall("glEnable GL_LIGHTING");
91 } else {
92 glDisable(GL_LIGHTING);
93 checkGLcall("glDisable GL_LIGHTING");
97 static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
99 enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE];
100 static UINT once;
102 /* No z test without depth stencil buffers */
103 if (!state->fb->depth_stencil)
105 TRACE("No Z buffer - disabling depth test\n");
106 zenable = WINED3D_ZB_FALSE;
109 switch (zenable)
111 case WINED3D_ZB_FALSE:
112 glDisable(GL_DEPTH_TEST);
113 checkGLcall("glDisable GL_DEPTH_TEST");
114 break;
115 case WINED3D_ZB_TRUE:
116 glEnable(GL_DEPTH_TEST);
117 checkGLcall("glEnable GL_DEPTH_TEST");
118 break;
119 case WINED3D_ZB_USEW:
120 glEnable(GL_DEPTH_TEST);
121 checkGLcall("glEnable GL_DEPTH_TEST");
122 FIXME("W buffer is not well handled\n");
123 break;
124 default:
125 FIXME("Unrecognized depth buffer type %#x.\n", zenable);
126 break;
129 if (context->gl_info->supported[ARB_DEPTH_CLAMP])
131 if (!zenable && context->swapchain->device->strided_streams.position_transformed)
133 glEnable(GL_DEPTH_CLAMP);
134 checkGLcall("glEnable(GL_DEPTH_CLAMP)");
136 else
138 glDisable(GL_DEPTH_CLAMP);
139 checkGLcall("glDisable(GL_DEPTH_CLAMP)");
142 else if (!zenable && !once++)
143 FIXME("Z buffer disabled, but ARB_depth_clamp isn't supported.\n");
146 static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
148 /* glFrontFace() is set in context.c at context init and on an
149 * offscreen / onscreen rendering switch. */
150 switch (state->render_states[WINED3D_RS_CULLMODE])
152 case WINED3D_CULL_NONE:
153 glDisable(GL_CULL_FACE);
154 checkGLcall("glDisable GL_CULL_FACE");
155 break;
156 case WINED3D_CULL_CW:
157 glEnable(GL_CULL_FACE);
158 checkGLcall("glEnable GL_CULL_FACE");
159 glCullFace(GL_FRONT);
160 checkGLcall("glCullFace(GL_FRONT)");
161 break;
162 case WINED3D_CULL_CCW:
163 glEnable(GL_CULL_FACE);
164 checkGLcall("glEnable GL_CULL_FACE");
165 glCullFace(GL_BACK);
166 checkGLcall("glCullFace(GL_BACK)");
167 break;
168 default:
169 FIXME("Unrecognized cull mode %#x.\n",
170 state->render_states[WINED3D_RS_CULLMODE]);
174 static void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
176 switch (state->render_states[WINED3D_RS_SHADEMODE])
178 case WINED3D_SHADE_FLAT:
179 glShadeModel(GL_FLAT);
180 checkGLcall("glShadeModel(GL_FLAT)");
181 break;
182 case WINED3D_SHADE_GOURAUD:
183 glShadeModel(GL_SMOOTH);
184 checkGLcall("glShadeModel(GL_SMOOTH)");
185 break;
186 case WINED3D_SHADE_PHONG:
187 FIXME("WINED3D_SHADE_PHONG isn't supported.\n");
188 break;
189 default:
190 FIXME("Unrecognized shade mode %#x.\n",
191 state->render_states[WINED3D_RS_SHADEMODE]);
195 static void state_ditherenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
197 if (state->render_states[WINED3D_RS_DITHERENABLE])
199 glEnable(GL_DITHER);
200 checkGLcall("glEnable GL_DITHER");
202 else
204 glDisable(GL_DITHER);
205 checkGLcall("glDisable GL_DITHER");
209 static void state_zwritenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
211 if (state->render_states[WINED3D_RS_ZWRITEENABLE])
213 glDepthMask(1);
214 checkGLcall("glDepthMask(1)");
216 else
218 glDepthMask(0);
219 checkGLcall("glDepthMask(0)");
223 static GLenum gl_compare_func(enum wined3d_cmp_func f)
225 switch (f)
227 case WINED3D_CMP_NEVER:
228 return GL_NEVER;
229 case WINED3D_CMP_LESS:
230 return GL_LESS;
231 case WINED3D_CMP_EQUAL:
232 return GL_EQUAL;
233 case WINED3D_CMP_LESSEQUAL:
234 return GL_LEQUAL;
235 case WINED3D_CMP_GREATER:
236 return GL_GREATER;
237 case WINED3D_CMP_NOTEQUAL:
238 return GL_NOTEQUAL;
239 case WINED3D_CMP_GREATEREQUAL:
240 return GL_GEQUAL;
241 case WINED3D_CMP_ALWAYS:
242 return GL_ALWAYS;
243 default:
244 FIXME("Unrecognized compare function %#x.\n", f);
245 return GL_NONE;
249 static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
251 GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
253 if (!depth_func) return;
255 if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL)
257 static BOOL once;
258 /* There are a few issues with this: First, our inability to
259 * select a proper Z depth, most of the time we're stuck with
260 * D24S8, even if the app selects D32 or D16. There seem to be
261 * some other precision problems which have to be debugged to
262 * make NOTEQUAL and EQUAL work properly. */
263 if (!once)
265 once = TRUE;
266 FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet.\n");
270 glDepthFunc(depth_func);
271 checkGLcall("glDepthFunc");
274 static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
276 float col[4];
278 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col);
279 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
280 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
281 checkGLcall("glLightModel for MODEL_AMBIENT");
284 static void state_blendop_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
286 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
289 static GLenum gl_blend_op(enum wined3d_blend_op op)
291 switch (op)
293 case WINED3D_BLEND_OP_ADD:
294 return GL_FUNC_ADD_EXT;
295 case WINED3D_BLEND_OP_SUBTRACT:
296 return GL_FUNC_SUBTRACT_EXT;
297 case WINED3D_BLEND_OP_REVSUBTRACT:
298 return GL_FUNC_REVERSE_SUBTRACT_EXT;
299 case WINED3D_BLEND_OP_MIN:
300 return GL_MIN_EXT;
301 case WINED3D_BLEND_OP_MAX:
302 return GL_MAX_EXT;
303 default:
304 FIXME("Unhandled blend op %#x.\n", op);
305 return GL_NONE;
309 static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
311 const struct wined3d_gl_info *gl_info = context->gl_info;
312 GLenum blend_equation_alpha = GL_FUNC_ADD_EXT;
313 GLenum blend_equation = GL_FUNC_ADD_EXT;
315 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
316 if (state->render_states[WINED3D_RS_BLENDOPALPHA]
317 && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
319 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
320 return;
323 blend_equation = gl_blend_op(state->render_states[WINED3D_RS_BLENDOP]);
324 blend_equation_alpha = gl_blend_op(state->render_states[WINED3D_RS_BLENDOPALPHA]);
325 TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
327 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
329 GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
330 checkGLcall("glBlendEquationSeparateEXT");
332 else
334 GL_EXTCALL(glBlendEquationEXT(blend_equation));
335 checkGLcall("glBlendEquation");
339 static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_format *dst_format)
341 switch (factor)
343 case WINED3D_BLEND_ZERO:
344 return GL_ZERO;
345 case WINED3D_BLEND_ONE:
346 return GL_ONE;
347 case WINED3D_BLEND_SRCCOLOR:
348 return GL_SRC_COLOR;
349 case WINED3D_BLEND_INVSRCCOLOR:
350 return GL_ONE_MINUS_SRC_COLOR;
351 case WINED3D_BLEND_SRCALPHA:
352 return GL_SRC_ALPHA;
353 case WINED3D_BLEND_INVSRCALPHA:
354 return GL_ONE_MINUS_SRC_ALPHA;
355 case WINED3D_BLEND_DESTCOLOR:
356 return GL_DST_COLOR;
357 case WINED3D_BLEND_INVDESTCOLOR:
358 return GL_ONE_MINUS_DST_COLOR;
359 /* To compensate for the lack of format switching with backbuffer
360 * offscreen rendering, and with onscreen rendering, we modify the
361 * alpha test parameters for (INV)DESTALPHA if the render target
362 * doesn't support alpha blending. A nonexistent alpha channel
363 * returns 1.0, so WINED3D_BLEND_DESTALPHA becomes GL_ONE, and
364 * WINED3D_BLEND_INVDESTALPHA becomes GL_ZERO. */
365 case WINED3D_BLEND_DESTALPHA:
366 return dst_format->alpha_mask ? GL_DST_ALPHA : GL_ONE;
367 case WINED3D_BLEND_INVDESTALPHA:
368 return dst_format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
369 case WINED3D_BLEND_SRCALPHASAT:
370 return GL_SRC_ALPHA_SATURATE;
371 case WINED3D_BLEND_BLENDFACTOR:
372 return GL_CONSTANT_COLOR_EXT;
373 case WINED3D_BLEND_INVBLENDFACTOR:
374 return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
375 default:
376 FIXME("Unhandled blend factor %#x.\n", factor);
377 return GL_NONE;
381 static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
383 const struct wined3d_surface *target = state->fb->render_targets[0];
384 const struct wined3d_gl_info *gl_info = context->gl_info;
385 GLenum srcBlend, dstBlend;
386 enum wined3d_blend d3d_blend;
388 /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
389 * blending parameters to work. */
390 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]
391 || state->render_states[WINED3D_RS_EDGEANTIALIAS]
392 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
394 /* Disable blending in all cases even without pixelshaders.
395 * With blending on we could face a big performance penalty.
396 * The d3d9 visual test confirms the behavior. */
397 if (context->render_offscreen
398 && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
400 glDisable(GL_BLEND);
401 checkGLcall("glDisable GL_BLEND");
402 return;
403 } else {
404 glEnable(GL_BLEND);
405 checkGLcall("glEnable GL_BLEND");
407 } else {
408 glDisable(GL_BLEND);
409 checkGLcall("glDisable GL_BLEND");
410 /* Nothing more to do - get out */
411 return;
414 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
415 * source blending values which are still valid up to d3d9. They should
416 * not occur as dest blend values. */
417 d3d_blend = state->render_states[WINED3D_RS_SRCBLEND];
418 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
420 srcBlend = GL_SRC_ALPHA;
421 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
423 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
425 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
426 dstBlend = GL_SRC_ALPHA;
428 else
430 srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
431 dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
432 target->resource.format);
435 if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
436 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
438 glEnable(GL_LINE_SMOOTH);
439 checkGLcall("glEnable(GL_LINE_SMOOTH)");
440 if(srcBlend != GL_SRC_ALPHA) {
441 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param\n");
443 if(dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE) {
444 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param\n");
446 } else {
447 glDisable(GL_LINE_SMOOTH);
448 checkGLcall("glDisable(GL_LINE_SMOOTH)");
451 /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
452 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP)))
453 state_blendop(context, state, STATE_RENDER(WINED3D_RS_BLENDOPALPHA));
455 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
457 GLenum srcBlendAlpha, dstBlendAlpha;
459 /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
460 if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
462 WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
463 return;
466 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
467 * source blending values which are still valid up to d3d9. They should
468 * not occur as dest blend values. */
469 d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA];
470 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
472 srcBlendAlpha = GL_SRC_ALPHA;
473 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
475 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
477 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
478 dstBlendAlpha = GL_SRC_ALPHA;
480 else
482 srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
483 dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
484 target->resource.format);
487 GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
488 checkGLcall("glBlendFuncSeparateEXT");
489 } else {
490 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
491 glBlendFunc(srcBlend, dstBlend);
492 checkGLcall("glBlendFunc");
495 /* Colorkey fixup for stage 0 alphaop depends on
496 * WINED3D_RS_ALPHABLENDENABLE state, so it may need updating. */
497 if (state->render_states[WINED3D_RS_COLORKEYENABLE])
498 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
501 static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
503 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
506 static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
508 const struct wined3d_gl_info *gl_info = context->gl_info;
509 float col[4];
511 TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
513 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
514 GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
515 checkGLcall("glBlendColor");
518 static void state_alpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
520 int glParm = 0;
521 float ref;
522 BOOL enable_ckey = FALSE;
524 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
526 /* Find out if the texture on the first stage has a ckey set
527 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
528 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
529 * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
530 * in case it finds some texture+colorkeyenable combination which needs extra care.
532 if (state->textures[0])
534 struct wined3d_surface *surface = surface_from_resource(state->textures[0]->sub_resources[0]);
536 if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
537 enable_ckey = TRUE;
540 if (enable_ckey || context->last_was_ckey)
541 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
542 context->last_was_ckey = enable_ckey;
544 if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
545 || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
547 glEnable(GL_ALPHA_TEST);
548 checkGLcall("glEnable GL_ALPHA_TEST");
549 } else {
550 glDisable(GL_ALPHA_TEST);
551 checkGLcall("glDisable GL_ALPHA_TEST");
552 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
553 * enable call
555 return;
558 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
560 glParm = GL_NOTEQUAL;
561 ref = 0.0f;
563 else
565 ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
566 glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
568 if(glParm) {
569 glAlphaFunc(glParm, ref);
570 checkGLcall("glAlphaFunc");
574 static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
576 const struct wined3d_device *device = context->swapchain->device;
578 /* Vertex and pixel shader states will call a shader upload, don't do
579 * anything as long one of them has an update pending. */
580 if (isStateDirty(context, STATE_VDECL)
581 || isStateDirty(context, STATE_PIXELSHADER))
582 return;
584 device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
587 static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
589 DWORD enable = 0xFFFFFFFF;
590 DWORD disable = 0x00000000;
592 if (use_vs(state))
594 const struct wined3d_device *device = context->swapchain->device;
596 if (!device->vs_clipping)
598 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
599 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
600 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
601 * of that - don't do anything here and keep them disabled
603 if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
605 static BOOL warned = FALSE;
606 if(!warned) {
607 FIXME("Clipping not supported with vertex shaders\n");
608 warned = TRUE;
611 return;
614 /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
615 * hardcoded into the shader. Update the shader to update the enabled clipplanes */
616 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
618 device->shader_backend->shader_select(context, use_ps(state), TRUE);
619 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
620 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
624 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
625 * of already set values
628 /* If enabling / disabling all
629 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
631 if (state->render_states[WINED3D_RS_CLIPPING])
633 enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
634 disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
636 else
638 disable = 0xffffffff;
639 enable = 0x00;
642 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
643 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
644 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
645 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
646 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
647 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
649 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
650 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
651 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
652 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
653 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
654 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
657 static 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 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 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
707 else
709 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
711 checkGLcall("glMaterialf(GL_SHININESS)");
713 if (gl_info->supported[EXT_SECONDARY_COLOR])
715 glEnable(GL_COLOR_SUM_EXT);
717 else
719 TRACE("Specular colors cannot be enabled in this version of opengl\n");
721 checkGLcall("glEnable(GL_COLOR_SUM)");
723 if (gl_info->supported[NV_REGISTER_COMBINERS])
725 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
726 checkGLcall("glFinalCombinerInputNV()");
728 } else {
729 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
731 /* for the case of enabled lighting: */
732 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
733 checkGLcall("glMaterialfv");
735 /* for the case of disabled lighting: */
736 if (gl_info->supported[EXT_SECONDARY_COLOR])
738 glDisable(GL_COLOR_SUM_EXT);
740 else
742 TRACE("Specular colors cannot be disabled in this version of opengl\n");
744 checkGLcall("glDisable(GL_COLOR_SUM)");
746 if (gl_info->supported[NV_REGISTER_COMBINERS])
748 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
749 checkGLcall("glFinalCombinerInputNV()");
753 TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
754 state->material.diffuse.r, state->material.diffuse.g,
755 state->material.diffuse.b, state->material.diffuse.a);
756 TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
757 state->material.ambient.r, state->material.ambient.g,
758 state->material.ambient.b, state->material.ambient.a);
759 TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
760 state->material.specular.r, state->material.specular.g,
761 state->material.specular.b, state->material.specular.a);
762 TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
763 state->material.emissive.r, state->material.emissive.g,
764 state->material.emissive.b, state->material.emissive.a);
766 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
767 checkGLcall("glMaterialfv(GL_AMBIENT)");
768 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
769 checkGLcall("glMaterialfv(GL_DIFFUSE)");
770 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
771 checkGLcall("glMaterialfv(GL_EMISSION)");
774 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
776 const struct wined3d_gl_info *gl_info = context->gl_info;
777 unsigned int i;
779 /* Note the texture color applies to all textures whereas
780 * GL_TEXTURE_ENV_COLOR applies to active only. */
781 float col[4];
782 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
784 /* And now the default texture color as well */
785 for (i = 0; i < gl_info->limits.texture_stages; ++i)
787 /* Note the WINED3D_RS value applies to all textures, but GL has one
788 * per texture, so apply it now ready to be used! */
789 context_active_texture(context, gl_info, i);
791 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
792 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
796 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
797 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
799 const struct wined3d_gl_info *gl_info = context->gl_info;
801 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
802 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
803 GL_EXTCALL(glActiveStencilFaceEXT(face));
804 checkGLcall("glActiveStencilFaceEXT(...)");
805 glStencilFunc(func, ref, mask);
806 checkGLcall("glStencilFunc(...)");
807 glStencilOp(stencilFail, depthFail, stencilPass);
808 checkGLcall("glStencilOp(...)");
811 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
813 switch (op)
815 case WINED3D_STENCIL_OP_KEEP:
816 return GL_KEEP;
817 case WINED3D_STENCIL_OP_ZERO:
818 return GL_ZERO;
819 case WINED3D_STENCIL_OP_REPLACE:
820 return GL_REPLACE;
821 case WINED3D_STENCIL_OP_INCR_SAT:
822 return GL_INCR;
823 case WINED3D_STENCIL_OP_DECR_SAT:
824 return GL_DECR;
825 case WINED3D_STENCIL_OP_INVERT:
826 return GL_INVERT;
827 case WINED3D_STENCIL_OP_INCR:
828 return GL_INCR_WRAP_EXT;
829 case WINED3D_STENCIL_OP_DECR:
830 return GL_DECR_WRAP_EXT;
831 default:
832 FIXME("Unrecognized stencil op %#x.\n", op);
833 return GL_KEEP;
837 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
839 const struct wined3d_gl_info *gl_info = context->gl_info;
840 DWORD onesided_enable = FALSE;
841 DWORD twosided_enable = FALSE;
842 GLint func = GL_ALWAYS;
843 GLint func_ccw = GL_ALWAYS;
844 GLint ref = 0;
845 GLuint mask = 0;
846 GLint stencilFail = GL_KEEP;
847 GLint depthFail = GL_KEEP;
848 GLint stencilPass = GL_KEEP;
849 GLint stencilFail_ccw = GL_KEEP;
850 GLint depthFail_ccw = GL_KEEP;
851 GLint stencilPass_ccw = GL_KEEP;
853 /* No stencil test without a stencil buffer. */
854 if (!state->fb->depth_stencil)
856 glDisable(GL_STENCIL_TEST);
857 checkGLcall("glDisable GL_STENCIL_TEST");
858 return;
861 onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
862 twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
863 if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
864 func = GL_ALWAYS;
865 if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
866 func_ccw = GL_ALWAYS;
867 ref = state->render_states[WINED3D_RS_STENCILREF];
868 mask = state->render_states[WINED3D_RS_STENCILMASK];
869 stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
870 depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
871 stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
872 stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
873 depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
874 stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
876 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
877 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
878 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
879 onesided_enable, twosided_enable, ref, mask,
880 func, stencilFail, depthFail, stencilPass,
881 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
883 if (twosided_enable && onesided_enable) {
884 glEnable(GL_STENCIL_TEST);
885 checkGLcall("glEnable GL_STENCIL_TEST");
887 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
889 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
890 * which has an effect on the code below too. If we apply the front face
891 * afterwards, we are sure that the active stencil face is set to front,
892 * and other stencil functions which do not use two sided stencil do not have
893 * to set it back
895 renderstate_stencil_twosided(context, GL_BACK,
896 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
897 renderstate_stencil_twosided(context, GL_FRONT,
898 func, ref, mask, stencilFail, depthFail, stencilPass);
900 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
902 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
903 checkGLcall("glStencilFuncSeparateATI(...)");
904 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
905 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
906 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
907 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
908 } else {
909 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
912 else if(onesided_enable)
914 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
916 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
917 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
920 /* This code disables the ATI extension as well, since the standard stencil functions are equal
921 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
923 glEnable(GL_STENCIL_TEST);
924 checkGLcall("glEnable GL_STENCIL_TEST");
925 glStencilFunc(func, ref, mask);
926 checkGLcall("glStencilFunc(...)");
927 glStencilOp(stencilFail, depthFail, stencilPass);
928 checkGLcall("glStencilOp(...)");
929 } else {
930 glDisable(GL_STENCIL_TEST);
931 checkGLcall("glDisable GL_STENCIL_TEST");
935 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
937 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
938 const struct wined3d_gl_info *gl_info = context->gl_info;
940 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
941 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
942 glStencilMask(mask);
943 checkGLcall("glStencilMask");
944 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
945 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
946 glStencilMask(mask);
949 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
951 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
953 glStencilMask(mask);
954 checkGLcall("glStencilMask");
957 static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
960 const struct wined3d_gl_info *gl_info = context->gl_info;
961 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
963 if (!state->render_states[WINED3D_RS_FOGENABLE])
964 return;
966 /* Table fog on: Never use fog coords, and use per-fragment fog */
967 if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
969 glHint(GL_FOG_HINT, GL_NICEST);
970 if(context->fog_coord) {
971 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
972 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
973 context->fog_coord = FALSE;
976 /* Range fog is only used with per-vertex fog in d3d */
977 if (gl_info->supported[NV_FOG_DISTANCE])
979 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
980 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
982 return;
985 /* Otherwise use per-vertex fog in any case */
986 glHint(GL_FOG_HINT, GL_FASTEST);
988 if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
990 /* No fog at all, or transformed vertices: Use fog coord */
991 if(!context->fog_coord) {
992 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
993 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
994 context->fog_coord = TRUE;
997 else
999 /* Otherwise, use the fragment depth */
1000 if(context->fog_coord) {
1001 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1002 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1003 context->fog_coord = FALSE;
1006 if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
1008 if (gl_info->supported[NV_FOG_DISTANCE])
1010 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1011 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1013 else
1015 WARN("Range fog enabled, but not supported by this GL implementation.\n");
1018 else if (gl_info->supported[NV_FOG_DISTANCE])
1020 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1021 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1026 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
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 glFogf(GL_FOG_START, fogstart);
1067 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1068 TRACE("Fog Start == %f\n", fogstart);
1070 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 enum fogsource new_source;
1079 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
1081 if (!state->render_states[WINED3D_RS_FOGENABLE])
1083 /* No fog? Disable it, and we're done :-) */
1084 glDisableWINE(GL_FOG);
1085 checkGLcall("glDisable GL_FOG");
1086 return;
1089 /* Fog Rules:
1091 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1092 * It can use the Z value of the vertex, or the alpha component of the specular color.
1093 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1094 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1095 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1097 * FOGTABLEMODE != NONE:
1098 * The Z value is used, with the equation specified, no matter what vertex type.
1100 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1101 * Per vertex fog is calculated using the specified fog equation and the parameters
1103 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1104 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1105 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1108 * Rules for vertex fog with shaders:
1110 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1111 * the fog computation to happen during transformation while openGL expects it to happen
1112 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1113 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1114 * To solve this problem, WineD3D does:
1115 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1116 * shader,
1117 * and 2) disables the fog computation (in either the fixed function or programmable
1118 * rasterizer) if using a vertex program.
1120 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1121 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1122 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1123 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1124 * There are some GL differences between specular fog coords and vertex shaders though.
1126 * With table fog the vertex shader fog coordinate is ignored.
1128 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1129 * without shaders).
1132 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1133 * the system will apply only pixel(=table) fog effects."
1135 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
1137 if (use_vs(state))
1139 glFogi(GL_FOG_MODE, GL_LINEAR);
1140 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1141 new_source = FOGSOURCE_VS;
1143 else
1145 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
1147 /* If processed vertices are used, fall through to the NONE case */
1148 case WINED3D_FOG_EXP:
1149 if (!context->last_was_rhw)
1151 glFogi(GL_FOG_MODE, GL_EXP);
1152 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1153 new_source = FOGSOURCE_FFP;
1154 break;
1156 /* drop through */
1158 case WINED3D_FOG_EXP2:
1159 if (!context->last_was_rhw)
1161 glFogi(GL_FOG_MODE, GL_EXP2);
1162 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1163 new_source = FOGSOURCE_FFP;
1164 break;
1166 /* drop through */
1168 case WINED3D_FOG_LINEAR:
1169 if (!context->last_was_rhw)
1171 glFogi(GL_FOG_MODE, GL_LINEAR);
1172 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1173 new_source = FOGSOURCE_FFP;
1174 break;
1176 /* drop through */
1178 case WINED3D_FOG_NONE:
1179 /* Both are none? According to msdn the alpha channel of the specular
1180 * color contains a fog factor. Set it in drawStridedSlow.
1181 * Same happens with Vertexfog on transformed vertices
1183 new_source = FOGSOURCE_COORD;
1184 glFogi(GL_FOG_MODE, GL_LINEAR);
1185 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1186 break;
1188 default:
1189 FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
1190 state->render_states[WINED3D_RS_FOGVERTEXMODE]);
1191 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1194 } else {
1195 new_source = FOGSOURCE_FFP;
1197 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
1199 case WINED3D_FOG_EXP:
1200 glFogi(GL_FOG_MODE, GL_EXP);
1201 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1202 break;
1204 case WINED3D_FOG_EXP2:
1205 glFogi(GL_FOG_MODE, GL_EXP2);
1206 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1207 break;
1209 case WINED3D_FOG_LINEAR:
1210 glFogi(GL_FOG_MODE, GL_LINEAR);
1211 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1212 break;
1214 case WINED3D_FOG_NONE: /* Won't happen */
1215 default:
1216 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
1217 state->render_states[WINED3D_RS_FOGTABLEMODE]);
1221 glEnableWINE(GL_FOG);
1222 checkGLcall("glEnable GL_FOG");
1223 if (new_source != context->fog_source)
1225 context->fog_source = new_source;
1226 state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
1230 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1232 float col[4];
1234 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
1235 glFogfv(GL_FOG_COLOR, &col[0]);
1236 checkGLcall("glFog GL_FOG_COLOR");
1239 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1241 union {
1242 DWORD d;
1243 float f;
1244 } tmpvalue;
1246 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1247 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1248 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1251 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1253 const struct wined3d_device *device = context->swapchain->device;
1254 GLenum Parm = 0;
1256 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1257 * The vertex declaration will call this function if the fixed function pipeline is used.
1260 if(isStateDirty(context, STATE_VDECL)) {
1261 return;
1264 context->num_untracked_materials = 0;
1265 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1266 && state->render_states[WINED3D_RS_COLORVERTEX])
1268 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1269 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
1270 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
1271 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
1272 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
1274 if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1276 if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1277 Parm = GL_AMBIENT_AND_DIFFUSE;
1278 else
1279 Parm = GL_DIFFUSE;
1280 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1282 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1283 context->num_untracked_materials++;
1285 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1287 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1288 context->num_untracked_materials++;
1291 else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1293 Parm = GL_AMBIENT;
1294 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1296 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1297 context->num_untracked_materials++;
1299 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1301 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1302 context->num_untracked_materials++;
1305 else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1307 Parm = GL_EMISSION;
1308 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1310 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1311 context->num_untracked_materials++;
1314 else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1316 Parm = GL_SPECULAR;
1320 /* Nothing changed, return. */
1321 if (Parm == context->tracking_parm) return;
1323 if(!Parm) {
1324 glDisable(GL_COLOR_MATERIAL);
1325 checkGLcall("glDisable GL_COLOR_MATERIAL");
1326 } else {
1327 glColorMaterial(GL_FRONT_AND_BACK, Parm);
1328 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1329 glEnable(GL_COLOR_MATERIAL);
1330 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1333 /* Apparently calls to glMaterialfv are ignored for properties we're
1334 * tracking with glColorMaterial, so apply those here. */
1335 switch (context->tracking_parm) {
1336 case GL_AMBIENT_AND_DIFFUSE:
1337 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1338 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1339 checkGLcall("glMaterialfv");
1340 break;
1342 case GL_DIFFUSE:
1343 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1344 checkGLcall("glMaterialfv");
1345 break;
1347 case GL_AMBIENT:
1348 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1349 checkGLcall("glMaterialfv");
1350 break;
1352 case GL_EMISSION:
1353 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
1354 checkGLcall("glMaterialfv");
1355 break;
1357 case GL_SPECULAR:
1358 /* Only change material color if specular is enabled, otherwise it is set to black */
1359 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1361 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
1362 checkGLcall("glMaterialfv");
1364 else
1366 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1367 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1368 checkGLcall("glMaterialfv");
1370 break;
1373 context->tracking_parm = Parm;
1376 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1378 union
1380 DWORD d;
1381 struct wined3d_line_pattern lp;
1382 } tmppattern;
1383 tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
1385 TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1387 if (tmppattern.lp.repeat_factor)
1389 glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1390 checkGLcall("glLineStipple(repeat, linepattern)");
1391 glEnable(GL_LINE_STIPPLE);
1392 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1394 else
1396 glDisable(GL_LINE_STIPPLE);
1397 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1401 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1403 if (isStateDirty(context, STATE_VDECL))
1404 return;
1406 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1407 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1408 * by zero and is not properly defined in opengl, so avoid it
1410 if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
1411 && (context->swapchain->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1413 glEnable(GL_NORMALIZE);
1414 checkGLcall("glEnable(GL_NORMALIZE);");
1416 else
1418 glDisable(GL_NORMALIZE);
1419 checkGLcall("glDisable(GL_NORMALIZE);");
1423 static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1425 union {
1426 DWORD d;
1427 float f;
1428 } tmpvalue;
1430 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1431 if (tmpvalue.f != 1.0f)
1433 FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1435 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1436 if (tmpvalue.f != 64.0f)
1438 FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1443 static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1445 const struct wined3d_gl_info *gl_info = context->gl_info;
1446 union
1448 DWORD d;
1449 float f;
1450 } min, max;
1452 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1453 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1455 /* Max point size trumps min point size */
1456 if(min.f > max.f) {
1457 min.f = max.f;
1460 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1461 checkGLcall("glPointParameterfEXT(...)");
1462 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1463 checkGLcall("glPointParameterfEXT(...)");
1466 static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1468 const struct wined3d_gl_info *gl_info = context->gl_info;
1469 union
1471 DWORD d;
1472 float f;
1473 } min, max;
1475 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1476 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1478 /* Max point size trumps min point size */
1479 if(min.f > max.f) {
1480 min.f = max.f;
1483 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1484 checkGLcall("glPointParameterfARB(...)");
1485 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1486 checkGLcall("glPointParameterfARB(...)");
1489 static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1491 const struct wined3d_gl_info *gl_info = context->gl_info;
1492 /* TODO: Group this with the viewport */
1494 * POINTSCALEENABLE controls how point size value is treated. If set to
1495 * true, the point size is scaled with respect to height of viewport.
1496 * When set to false point size is in pixels.
1499 /* Default values */
1500 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1501 union {
1502 DWORD d;
1503 float f;
1504 } pointSize, A, B, C;
1506 pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
1507 A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
1508 B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
1509 C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
1511 if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1513 DWORD h = state->viewport.height;
1514 GLfloat scaleFactor;
1516 if (pointSize.f < gl_info->limits.pointsize_min)
1518 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1519 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1520 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1521 * are less than 1.0f. scale_factor = 1.0f / point_size.
1523 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1524 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1525 * is 1.0, but then accepts points below that and draws too small points
1527 pointSize.f = gl_info->limits.pointsize_min;
1529 else if(pointSize.f > gl_info->limits.pointsize_max)
1531 /* gl already scales the input to glPointSize,
1532 * d3d scales the result after the point size scale.
1533 * If the point size is bigger than the max size, use the
1534 * scaling to scale it bigger, and set the gl point size to max
1536 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1537 TRACE("scale: %f\n", scaleFactor);
1538 pointSize.f = gl_info->limits.pointsize_max;
1539 } else {
1540 scaleFactor = 1.0f;
1542 scaleFactor = powf(h * scaleFactor, 2);
1544 att[0] = A.f / scaleFactor;
1545 att[1] = B.f / scaleFactor;
1546 att[2] = C.f / scaleFactor;
1549 if (gl_info->supported[ARB_POINT_PARAMETERS])
1551 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1552 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1554 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1556 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1557 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1559 else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1561 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1564 glPointSize(pointSize.f);
1565 checkGLcall("glPointSize(...);");
1568 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1570 WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
1573 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1575 DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
1576 DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
1577 DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
1578 DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
1580 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1581 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1582 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1583 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1584 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1585 glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1586 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1587 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1588 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1589 checkGLcall("glColorMask(...)");
1591 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1592 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1594 FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1595 mask0, mask1, mask2, mask3);
1596 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1600 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1602 GL_EXTCALL(glColorMaskIndexedEXT(index,
1603 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1604 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1605 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1606 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1609 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1611 set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
1614 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1616 set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
1619 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1621 set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
1624 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1626 set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
1629 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1631 if (state->render_states[WINED3D_RS_LOCALVIEWER])
1633 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1634 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1635 } else {
1636 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1637 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1641 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1643 if (state->render_states[WINED3D_RS_LASTPIXEL])
1645 TRACE("Last Pixel Drawing Enabled\n");
1647 else
1649 static BOOL warned;
1650 if (!warned) {
1651 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1652 warned = TRUE;
1653 } else {
1654 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1659 static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1661 static BOOL warned;
1663 /* TODO: NV_POINT_SPRITE */
1664 if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1666 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1667 FIXME("Point sprites not supported\n");
1668 warned = TRUE;
1672 static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1674 if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1676 glEnable(GL_POINT_SPRITE_ARB);
1677 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1678 } else {
1679 glDisable(GL_POINT_SPRITE_ARB);
1680 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1684 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1686 if (state->render_states[WINED3D_RS_WRAP0]
1687 || state->render_states[WINED3D_RS_WRAP1]
1688 || state->render_states[WINED3D_RS_WRAP2]
1689 || state->render_states[WINED3D_RS_WRAP3]
1690 || state->render_states[WINED3D_RS_WRAP4]
1691 || state->render_states[WINED3D_RS_WRAP5]
1692 || state->render_states[WINED3D_RS_WRAP6]
1693 || state->render_states[WINED3D_RS_WRAP7]
1694 || state->render_states[WINED3D_RS_WRAP8]
1695 || state->render_states[WINED3D_RS_WRAP9]
1696 || state->render_states[WINED3D_RS_WRAP10]
1697 || state->render_states[WINED3D_RS_WRAP11]
1698 || state->render_states[WINED3D_RS_WRAP12]
1699 || state->render_states[WINED3D_RS_WRAP13]
1700 || state->render_states[WINED3D_RS_WRAP14]
1701 || state->render_states[WINED3D_RS_WRAP15])
1702 FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
1705 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1707 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1708 WARN("Multisample antialiasing not supported by GL.\n");
1711 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1713 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1715 glEnable(GL_MULTISAMPLE_ARB);
1716 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1717 } else {
1718 glDisable(GL_MULTISAMPLE_ARB);
1719 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1723 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1725 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
1727 glEnable(GL_SCISSOR_TEST);
1728 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1729 } else {
1730 glDisable(GL_SCISSOR_TEST);
1731 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1735 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1736 * OpenGL the bias is specified in units of "the smallest value that is
1737 * guaranteed to produce a resolvable offset for a given implementation". To
1738 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1739 * There's no practical way to retrieve that value from a given GL
1740 * implementation, but the D3D application has essentially the same problem,
1741 * which makes a guess of the depth buffer format's highest possible value a
1742 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1743 * depth slope, and doesn't need to be scaled. */
1744 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1746 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
1747 || state->render_states[WINED3D_RS_DEPTHBIAS])
1749 const struct wined3d_surface *depth = state->fb->depth_stencil;
1750 float scale;
1752 union
1754 DWORD d;
1755 float f;
1756 } scale_bias, const_bias;
1758 scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
1759 const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
1761 glEnable(GL_POLYGON_OFFSET_FILL);
1762 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1764 if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
1766 float bias = -(float)const_bias.d;
1767 glPolygonOffset(bias, bias);
1768 checkGLcall("glPolygonOffset");
1770 else
1772 if (depth)
1774 const struct wined3d_format *fmt = depth->resource.format;
1775 scale = powf(2, fmt->depth_size) - 1;
1776 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
1777 debug_d3dformat(fmt->id), scale);
1779 else
1781 /* The context manager will reapply this state on a depth stencil change */
1782 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
1783 scale = 0.0f;
1786 glPolygonOffset(scale_bias.f, const_bias.f * scale);
1787 checkGLcall("glPolygonOffset(...)");
1790 else
1792 glDisable(GL_POLYGON_OFFSET_FILL);
1793 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1797 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1799 if (state->render_states[WINED3D_RS_ZVISIBLE])
1800 FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
1803 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1805 if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
1807 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1808 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1809 } else {
1810 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1811 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1815 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1817 if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
1818 FIXME("Stippled Alpha not supported yet.\n");
1821 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1823 if (state->render_states[WINED3D_RS_ANTIALIAS])
1824 FIXME("Antialias not supported yet.\n");
1827 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1829 if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
1830 FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
1831 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
1834 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1836 if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
1837 FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
1838 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
1841 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1843 union {
1844 DWORD d;
1845 float f;
1846 } tmpvalue;
1847 tmpvalue.f = 1.0f;
1849 if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
1851 static BOOL displayed = FALSE;
1853 tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
1854 if(!displayed)
1855 FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1857 displayed = TRUE;
1861 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1863 if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
1864 FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
1865 state->render_states[WINED3D_RS_POSITIONDEGREE]);
1868 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1870 if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
1871 FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
1872 state->render_states[WINED3D_RS_NORMALDEGREE]);
1875 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1877 if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
1878 FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1879 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
1882 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1884 union {
1885 DWORD d;
1886 float f;
1887 } zmin, zmax;
1889 const struct wined3d_gl_info *gl_info = context->gl_info;
1891 if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1893 zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
1894 zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
1896 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1897 * In d3d9 test is not performed in this case*/
1898 if (zmin.f <= zmax.f)
1900 glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1901 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1902 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1903 checkGLcall("glDepthBoundsEXT(...)");
1905 else {
1906 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1907 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1910 else {
1911 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1912 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1915 state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
1918 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1920 if (state->render_states[WINED3D_RS_WRAPU])
1921 FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
1924 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1926 if (state->render_states[WINED3D_RS_WRAPV])
1927 FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
1930 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1932 if (state->render_states[WINED3D_RS_MONOENABLE])
1933 FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
1936 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1938 if (state->render_states[WINED3D_RS_ROP2])
1939 FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
1942 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1944 if (state->render_states[WINED3D_RS_PLANEMASK])
1945 FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
1948 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1950 if (state->render_states[WINED3D_RS_SUBPIXEL])
1951 FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
1954 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1956 if (state->render_states[WINED3D_RS_SUBPIXELX])
1957 FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
1960 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1962 if (state->render_states[WINED3D_RS_STIPPLEENABLE])
1963 FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
1966 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1968 if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
1969 FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
1972 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1974 if (state->render_states[WINED3D_RS_ANISOTROPY])
1975 FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
1978 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1980 if (state->render_states[WINED3D_RS_FLUSHBATCH])
1981 FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
1984 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1986 if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
1987 FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
1990 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1992 if (state->render_states[WINED3D_RS_EXTENTS])
1993 FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
1996 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1998 if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
1999 FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
2002 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2004 if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
2005 FIXME("Software vertex processing not implemented.\n");
2008 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2009 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2010 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2011 * flag specifies the complement of the input should be used. */
2012 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2013 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2015 /* Calculate the operand */
2016 if (complement) {
2017 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2018 else *operand = GL_ONE_MINUS_SRC_COLOR;
2019 } else {
2020 if (from_alpha) *operand = GL_SRC_ALPHA;
2021 else *operand = GL_SRC_COLOR;
2024 /* Calculate the source */
2025 switch (arg & WINED3DTA_SELECTMASK) {
2026 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2027 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2028 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2029 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2030 case WINED3DTA_SPECULAR:
2032 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2033 * 'Secondary color' and isn't supported until base GL supports it
2034 * There is no concept of temp registers as far as I can tell
2036 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2037 *source = GL_TEXTURE;
2038 break;
2039 default:
2040 FIXME("Unrecognized texture arg %#x\n", arg);
2041 *source = GL_TEXTURE;
2042 break;
2046 /* Setup the texture operations texture stage states */
2047 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2048 BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2050 GLenum src1, src2, src3;
2051 GLenum opr1, opr2, opr3;
2052 GLenum comb_target;
2053 GLenum src0_target, src1_target, src2_target;
2054 GLenum opr0_target, opr1_target, opr2_target;
2055 GLenum scal_target;
2056 GLenum opr=0, invopr, src3_target, opr3_target;
2057 BOOL Handled = FALSE;
2059 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2061 /* This is called by a state handler which has the gl lock held and a context for the thread */
2063 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2064 the form (a1 <operation> a2). However, some of the more complex operations
2065 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2066 in a third parameter called a0. Therefore these are operations of the form
2067 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2069 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2070 functions below, expect their syntax to differ slightly to those listed in the
2071 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2072 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2074 if (isAlpha)
2076 comb_target = GL_COMBINE_ALPHA;
2077 src0_target = GL_SOURCE0_ALPHA;
2078 src1_target = GL_SOURCE1_ALPHA;
2079 src2_target = GL_SOURCE2_ALPHA;
2080 opr0_target = GL_OPERAND0_ALPHA;
2081 opr1_target = GL_OPERAND1_ALPHA;
2082 opr2_target = GL_OPERAND2_ALPHA;
2083 scal_target = GL_ALPHA_SCALE;
2085 else
2087 comb_target = GL_COMBINE_RGB;
2088 src0_target = GL_SOURCE0_RGB;
2089 src1_target = GL_SOURCE1_RGB;
2090 src2_target = GL_SOURCE2_RGB;
2091 opr0_target = GL_OPERAND0_RGB;
2092 opr1_target = GL_OPERAND1_RGB;
2093 opr2_target = GL_OPERAND2_RGB;
2094 scal_target = GL_RGB_SCALE;
2097 /* If a texture stage references an invalid texture unit the stage just
2098 * passes through the result from the previous stage */
2099 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2101 arg1 = WINED3DTA_CURRENT;
2102 op = WINED3D_TOP_SELECT_ARG1;
2105 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2107 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2108 } else {
2109 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2111 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2112 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2114 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2116 Handled = TRUE; /* Assume will be handled */
2118 /* Other texture operations require special extensions: */
2119 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2121 if (isAlpha) {
2122 opr = GL_SRC_ALPHA;
2123 invopr = GL_ONE_MINUS_SRC_ALPHA;
2124 src3_target = GL_SOURCE3_ALPHA_NV;
2125 opr3_target = GL_OPERAND3_ALPHA_NV;
2126 } else {
2127 opr = GL_SRC_COLOR;
2128 invopr = GL_ONE_MINUS_SRC_COLOR;
2129 src3_target = GL_SOURCE3_RGB_NV;
2130 opr3_target = GL_OPERAND3_RGB_NV;
2132 switch (op)
2134 case WINED3D_TOP_DISABLE: /* Only for alpha */
2135 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2136 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2137 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2138 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2139 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2140 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2141 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2142 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2143 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2144 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2145 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2146 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2147 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2148 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2149 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2150 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2151 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2152 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2153 break;
2154 case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
2155 case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
2156 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2157 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2158 if (op == WINED3D_TOP_SELECT_ARG1)
2160 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2161 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2162 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2163 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2164 } else {
2165 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2166 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2167 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2168 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2170 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2171 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2172 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2173 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2174 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2175 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2176 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2177 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2178 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2179 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2180 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2181 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2182 break;
2184 case WINED3D_TOP_MODULATE:
2185 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2186 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2187 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2188 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2189 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2190 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2191 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2192 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2193 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2194 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2195 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2196 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2197 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2198 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2199 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2200 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2201 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2202 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2203 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2204 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2205 break;
2206 case WINED3D_TOP_MODULATE_2X:
2207 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2208 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2209 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2210 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2211 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2212 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2213 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2214 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2215 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2216 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2217 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2218 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2219 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2220 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2221 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2222 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2223 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2224 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2225 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2226 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2227 break;
2228 case WINED3D_TOP_MODULATE_4X:
2229 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2230 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2231 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2232 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2233 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2234 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2235 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2236 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2237 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2238 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2239 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2240 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2241 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2242 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2243 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2244 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2245 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2246 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2247 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2248 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2249 break;
2251 case WINED3D_TOP_ADD:
2252 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2253 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2254 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2255 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2256 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2257 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2258 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2259 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2260 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2261 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2262 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2263 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2264 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2265 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2266 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2267 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2268 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2269 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2270 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2271 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2272 break;
2274 case WINED3D_TOP_ADD_SIGNED:
2275 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2276 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2277 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2278 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2279 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2280 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2281 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2282 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2283 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2284 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2285 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2286 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2287 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2288 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2289 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2290 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2291 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2292 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2293 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2294 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2295 break;
2297 case WINED3D_TOP_ADD_SIGNED_2X:
2298 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2299 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2300 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2301 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2302 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2303 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2304 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2305 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2306 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2307 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2308 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2309 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2310 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2311 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2312 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2313 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2314 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2315 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2316 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2317 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2318 break;
2320 case WINED3D_TOP_ADD_SMOOTH:
2321 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2322 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2323 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2324 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2325 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2326 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2327 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2328 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2329 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2330 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2331 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2332 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2333 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2334 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2335 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2336 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2337 switch (opr1) {
2338 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2339 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2340 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2341 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2343 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2344 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2345 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2346 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2347 break;
2349 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2350 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2351 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2352 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2353 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2354 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2355 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2356 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
2357 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
2358 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2359 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2360 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2361 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2362 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2363 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2364 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
2365 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
2366 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2367 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2368 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2369 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2370 break;
2371 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2372 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2373 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2374 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2375 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2376 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2377 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2378 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2379 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2380 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2381 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2382 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2383 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2384 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2385 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2386 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2387 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2388 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2389 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2390 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2391 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2392 break;
2393 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2394 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2395 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2396 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2397 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2398 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2399 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2400 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
2401 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
2402 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2403 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2404 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2405 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2406 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2407 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2408 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
2409 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
2410 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2411 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2412 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2413 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2414 break;
2415 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2416 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2417 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2418 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2419 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2420 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2421 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2422 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2423 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2424 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2425 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2426 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2427 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2428 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2429 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2430 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2431 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2432 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2433 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2434 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2435 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2436 break;
2437 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2438 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2439 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2440 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2441 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2442 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2443 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2444 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2445 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2446 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2447 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2448 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2449 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2450 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2451 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2452 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2453 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2454 switch (opr) {
2455 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2456 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2458 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2459 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2460 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2461 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2462 break;
2463 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2464 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2465 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2466 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2467 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2468 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2469 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2470 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2471 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2472 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2473 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2474 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2475 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2476 switch (opr1) {
2477 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2478 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2480 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2481 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2482 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2483 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2484 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2485 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2486 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2487 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2488 break;
2489 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2490 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2491 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2492 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2493 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2494 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2495 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2496 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2497 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2498 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2499 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2500 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2501 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2502 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2503 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2504 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2505 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2506 switch (opr1) {
2507 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2508 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2509 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2510 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2512 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2513 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2514 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2515 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2516 break;
2517 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2518 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2519 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2520 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2521 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2522 switch (opr1) {
2523 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2524 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2525 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2526 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2528 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2529 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2530 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2531 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2532 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2533 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2534 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2535 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2536 switch (opr1) {
2537 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2538 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2540 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2541 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2542 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2543 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2544 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2545 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2546 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2547 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2548 break;
2549 case WINED3D_TOP_MULTIPLY_ADD:
2550 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2551 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2552 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2553 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2554 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2555 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2556 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2557 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2558 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2559 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2560 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2561 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2562 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2563 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2564 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2565 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2566 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2567 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2568 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2569 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2570 break;
2572 case WINED3D_TOP_BUMPENVMAP:
2573 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
2574 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2576 default:
2577 Handled = FALSE;
2579 if (Handled) {
2580 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2581 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2583 return;
2585 } /* GL_NV_texture_env_combine4 */
2587 Handled = TRUE; /* Again, assume handled */
2588 switch (op) {
2589 case WINED3D_TOP_DISABLE: /* Only for alpha */
2590 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2591 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2592 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2593 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2594 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2595 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2596 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2597 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2598 break;
2599 case WINED3D_TOP_SELECT_ARG1:
2600 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2601 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2602 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2603 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2604 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2605 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2606 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2607 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2608 break;
2609 case WINED3D_TOP_SELECT_ARG2:
2610 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2611 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2612 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2613 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2614 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2615 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2616 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2617 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2618 break;
2619 case WINED3D_TOP_MODULATE:
2620 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2621 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2622 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2623 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2624 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2625 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2626 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2627 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2628 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2629 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2630 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2631 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2632 break;
2633 case WINED3D_TOP_MODULATE_2X:
2634 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2635 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2636 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2637 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2638 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2639 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2640 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2641 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2642 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2643 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2644 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2645 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2646 break;
2647 case WINED3D_TOP_MODULATE_4X:
2648 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2649 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2650 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2651 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2652 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2653 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2654 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2655 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2656 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2657 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2658 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2659 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2660 break;
2661 case WINED3D_TOP_ADD:
2662 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2663 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2664 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2665 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2666 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2667 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2668 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2669 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2670 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2671 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2672 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2673 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2674 break;
2675 case WINED3D_TOP_ADD_SIGNED:
2676 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2677 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2678 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2679 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2680 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2681 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2682 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2683 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2684 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2685 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2686 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2687 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2688 break;
2689 case WINED3D_TOP_ADD_SIGNED_2X:
2690 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2691 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2692 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2693 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2694 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2695 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2696 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2697 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2698 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2699 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2700 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2701 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2702 break;
2703 case WINED3D_TOP_SUBTRACT:
2704 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2706 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2707 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2708 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2709 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2710 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2711 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2712 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2713 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2714 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2715 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2716 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2717 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2718 } else {
2719 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2721 break;
2723 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2724 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2725 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2726 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2727 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2728 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2729 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2730 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2731 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2732 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2733 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2734 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
2735 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2736 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2737 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2738 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2739 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2740 break;
2741 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2742 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2743 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2744 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2745 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2746 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2747 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2748 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2749 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2750 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2751 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2752 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2753 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2754 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2755 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2756 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2757 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2758 break;
2759 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2760 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2761 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2762 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2763 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2764 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2765 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2766 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2767 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2768 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2769 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2770 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
2771 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2772 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2773 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2774 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2775 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2776 break;
2777 case WINED3D_TOP_BLEND_CURRENT_ALPHA:
2778 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2779 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2780 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2781 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2782 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2783 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2784 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2785 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2786 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2787 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2788 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
2789 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2790 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2791 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2792 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2793 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2794 break;
2795 case WINED3D_TOP_DOTPRODUCT3:
2796 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2798 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2799 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2801 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2803 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2804 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2805 } else {
2806 FIXME("This version of opengl does not support GL_DOT3\n");
2808 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2809 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2810 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2811 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2812 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2813 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2814 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2815 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2816 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2817 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2818 break;
2819 case WINED3D_TOP_LERP:
2820 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2821 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2822 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2823 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2824 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2825 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2826 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2827 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2828 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2829 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2830 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2831 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2832 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2833 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2834 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2835 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2836 break;
2837 case WINED3D_TOP_ADD_SMOOTH:
2838 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2840 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2841 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2842 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2843 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2844 switch (opr1) {
2845 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2846 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2847 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2848 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2850 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2851 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2852 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2853 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2854 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2855 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2856 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2857 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2858 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2859 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2860 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2861 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2862 } else
2863 Handled = FALSE;
2864 break;
2865 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2866 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2868 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2869 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2870 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2871 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2872 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2873 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2874 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2875 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2876 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2877 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2878 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2879 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2880 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2881 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2882 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2883 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2884 } else
2885 Handled = FALSE;
2886 break;
2887 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2888 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2890 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2891 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2892 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2893 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2894 switch (opr1) {
2895 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2896 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2897 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2898 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2900 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2901 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2902 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2903 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2904 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2905 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2906 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2907 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2908 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2909 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2910 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2911 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2912 } else
2913 Handled = FALSE;
2914 break;
2915 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2916 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2918 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2919 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2920 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2921 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2922 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2923 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2924 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2925 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2926 switch (opr1) {
2927 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2928 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2929 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2930 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2932 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2933 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2934 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2935 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2936 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2937 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2938 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2939 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2940 } else
2941 Handled = FALSE;
2942 break;
2943 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2944 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2946 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2947 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2948 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2949 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2950 switch (opr1) {
2951 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2952 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2953 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2954 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2956 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2957 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2958 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2959 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2960 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2961 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2962 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2963 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2964 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2965 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2966 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2967 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2968 } else
2969 Handled = FALSE;
2970 break;
2971 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2972 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2974 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2975 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2976 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2977 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2978 switch (opr1) {
2979 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2980 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2981 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2982 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2984 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2985 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2986 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2987 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2988 switch (opr1) {
2989 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2990 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2991 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2992 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2994 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2995 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2996 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2997 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2998 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2999 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3000 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3001 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3002 } else
3003 Handled = FALSE;
3004 break;
3005 case WINED3D_TOP_MULTIPLY_ADD:
3006 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3008 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3009 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3010 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3011 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3012 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3013 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3014 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3015 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3016 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3017 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3018 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3019 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3020 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3021 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3022 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3023 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3024 } else
3025 Handled = FALSE;
3026 break;
3027 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3028 case WINED3D_TOP_BUMPENVMAP:
3029 if (gl_info->supported[NV_TEXTURE_SHADER2])
3031 /* Technically texture shader support without register combiners is possible, but not expected to occur
3032 * on real world cards, so for now a fixme should be enough
3034 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3036 default:
3037 Handled = FALSE;
3040 if (Handled) {
3041 BOOL combineOK = TRUE;
3042 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3044 DWORD op2;
3046 if (isAlpha)
3047 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3048 else
3049 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3051 /* Note: If COMBINE4 in effect can't go back to combine! */
3052 switch (op2)
3054 case WINED3D_TOP_ADD_SMOOTH:
3055 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3056 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3057 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3058 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3059 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3060 case WINED3D_TOP_MULTIPLY_ADD:
3061 /* Ignore those implemented in both cases */
3062 switch (op)
3064 case WINED3D_TOP_SELECT_ARG1:
3065 case WINED3D_TOP_SELECT_ARG2:
3066 combineOK = FALSE;
3067 Handled = FALSE;
3068 break;
3069 default:
3070 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3071 return;
3076 if (combineOK)
3078 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3079 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3081 return;
3085 /* After all the extensions, if still unhandled, report fixme */
3086 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3090 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3092 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3093 const struct wined3d_device *device = context->swapchain->device;
3094 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3095 DWORD mapped_stage = device->texUnitMap[stage];
3096 const struct wined3d_gl_info *gl_info = context->gl_info;
3098 TRACE("Setting color op for stage %d\n", stage);
3100 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3101 if (use_ps(state)) return;
3103 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3105 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3107 if (tex_used && mapped_stage >= gl_info->limits.textures)
3109 FIXME("Attempt to enable unsupported stage!\n");
3110 return;
3112 context_active_texture(context, gl_info, mapped_stage);
3115 if (stage >= state->lowest_disabled_stage)
3117 TRACE("Stage disabled\n");
3118 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3120 /* Disable everything here */
3121 glDisable(GL_TEXTURE_2D);
3122 checkGLcall("glDisable(GL_TEXTURE_2D)");
3123 glDisable(GL_TEXTURE_3D);
3124 checkGLcall("glDisable(GL_TEXTURE_3D)");
3125 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3127 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3128 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3130 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3132 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3133 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3136 /* All done */
3137 return;
3140 /* The sampler will also activate the correct texture dimensions, so no
3141 * need to do it here if the sampler for this stage is dirty. */
3142 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3143 texture_activate_dimensions(state->textures[stage], gl_info);
3145 set_tex_op(gl_info, state, FALSE, stage,
3146 state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3147 state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3148 state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3149 state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3152 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3154 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3155 const struct wined3d_device *device = context->swapchain->device;
3156 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3157 DWORD mapped_stage = device->texUnitMap[stage];
3158 const struct wined3d_gl_info *gl_info = context->gl_info;
3159 DWORD op, arg1, arg2, arg0;
3161 TRACE("Setting alpha op for stage %d\n", stage);
3162 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3163 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3165 if (tex_used && mapped_stage >= gl_info->limits.textures)
3167 FIXME("Attempt to enable unsupported stage!\n");
3168 return;
3170 context_active_texture(context, gl_info, mapped_stage);
3173 op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3174 arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3175 arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3176 arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3178 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3180 struct wined3d_texture *texture = state->textures[0];
3181 GLenum texture_dimensions = texture->target;
3183 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3185 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3187 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3189 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3190 * properly. On the other hand applications can still use texture combiners apparently. This code
3191 * takes care that apps cannot remove the texture's alpha channel entirely.
3193 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3194 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3195 * and alpha component of diffuse color to draw things like translucent text and perform other
3196 * blending effects.
3198 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3199 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3200 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3201 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3202 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3203 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3204 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3205 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3206 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3207 * alpha.
3209 * What to do with multitexturing? So far no app has been found that uses color keying with
3210 * multitexturing */
3211 if (op == WINED3D_TOP_DISABLE)
3213 arg1 = WINED3DTA_TEXTURE;
3214 op = WINED3D_TOP_SELECT_ARG1;
3216 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3218 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3220 arg2 = WINED3DTA_TEXTURE;
3221 op = WINED3D_TOP_MODULATE;
3223 else arg1 = WINED3DTA_TEXTURE;
3225 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3227 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3229 arg1 = WINED3DTA_TEXTURE;
3230 op = WINED3D_TOP_MODULATE;
3232 else arg2 = WINED3DTA_TEXTURE;
3238 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3239 * this if block here, and the other code(color keying, texture unit selection) are the same
3241 TRACE("Setting alpha op for stage %d\n", stage);
3242 if (gl_info->supported[NV_REGISTER_COMBINERS])
3244 set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3245 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3247 else
3249 set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3253 static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3255 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3256 const struct wined3d_device *device = context->swapchain->device;
3257 const struct wined3d_gl_info *gl_info = context->gl_info;
3258 DWORD mapped_stage = device->texUnitMap[texUnit];
3259 BOOL generated;
3260 int coordIdx;
3262 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3263 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3265 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3266 return;
3269 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3270 if (mapped_stage >= gl_info->limits.textures) return;
3272 context_active_texture(context, gl_info, mapped_stage);
3273 generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3274 coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3276 set_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3277 state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3278 generated, context->last_was_rhw,
3279 device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3280 ? device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3281 : WINED3DFMT_UNKNOWN,
3282 device->frag_pipe->ffp_proj_control);
3284 /* The sampler applying function calls us if this changes */
3285 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3287 if(generated) {
3288 FIXME("Non-power2 texture being used with generated texture coords\n");
3290 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3291 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3292 if (!use_ps(state))
3294 TRACE("Non power two matrix multiply fixup\n");
3295 glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3300 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3302 unsigned int texture_idx;
3304 for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3306 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3307 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3311 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3312 GLuint *curVBO, const struct wined3d_state *state)
3314 const struct wined3d_device *device = context->swapchain->device;
3315 const struct wined3d_gl_info *gl_info = context->gl_info;
3316 unsigned int mapped_stage = 0;
3317 unsigned int textureNo = 0;
3319 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3321 int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3323 mapped_stage = device->texUnitMap[textureNo];
3324 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3326 if (mapped_stage >= gl_info->limits.texture_coords)
3328 FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3329 continue;
3332 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3334 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3336 TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3337 textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3339 if (*curVBO != e->data.buffer_object)
3341 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3342 checkGLcall("glBindBufferARB");
3343 *curVBO = e->data.buffer_object;
3346 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3347 checkGLcall("glClientActiveTextureARB");
3349 /* The coords to supply depend completely on the fvf / vertex shader */
3350 glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3351 e->data.addr + state->load_base_vertex_index * e->stride);
3352 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3354 else
3356 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3359 if (gl_info->supported[NV_REGISTER_COMBINERS])
3361 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3362 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3364 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3368 checkGLcall("loadTexCoords");
3371 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3373 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3374 const struct wined3d_device *device = context->swapchain->device;
3375 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3376 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3377 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3378 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3379 const struct wined3d_gl_info *gl_info = context->gl_info;
3380 DWORD mapped_stage = device->texUnitMap[stage];
3382 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3384 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3385 return;
3388 if (mapped_stage >= gl_info->limits.fragment_samplers)
3390 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3391 return;
3393 context_active_texture(context, gl_info, mapped_stage);
3395 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3397 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3398 * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3399 * means use the vertex position (camera-space) as the input texture coordinates
3400 * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3401 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3402 * to the TEXCOORDINDEX value
3404 switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3406 case WINED3DTSS_TCI_PASSTHRU:
3407 /* Use the specified texture coordinates contained within the
3408 * vertex format. This value resolves to zero. */
3409 glDisable(GL_TEXTURE_GEN_S);
3410 glDisable(GL_TEXTURE_GEN_T);
3411 glDisable(GL_TEXTURE_GEN_R);
3412 glDisable(GL_TEXTURE_GEN_Q);
3413 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3414 break;
3416 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3417 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3418 * as the input texture coordinates for this stage's texture transformation. This
3419 * equates roughly to EYE_LINEAR */
3421 glMatrixMode(GL_MODELVIEW);
3422 glPushMatrix();
3423 glLoadIdentity();
3424 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3425 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3426 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3427 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3428 glPopMatrix();
3429 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3431 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3432 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3433 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3434 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3436 glEnable(GL_TEXTURE_GEN_S);
3437 glEnable(GL_TEXTURE_GEN_T);
3438 glEnable(GL_TEXTURE_GEN_R);
3439 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3441 break;
3443 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3444 /* Note that NV_TEXGEN_REFLECTION support is implied when
3445 * ARB_TEXTURE_CUBE_MAP is supported */
3446 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3448 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3449 break;
3452 glMatrixMode(GL_MODELVIEW);
3453 glPushMatrix();
3454 glLoadIdentity();
3455 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3456 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3457 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3458 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3459 glPopMatrix();
3460 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3462 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3463 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3464 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3465 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3467 glEnable(GL_TEXTURE_GEN_S);
3468 glEnable(GL_TEXTURE_GEN_T);
3469 glEnable(GL_TEXTURE_GEN_R);
3470 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3472 break;
3474 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3475 /* Note that NV_TEXGEN_REFLECTION support is implied when
3476 * ARB_TEXTURE_CUBE_MAP is supported */
3477 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3479 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3480 break;
3483 glMatrixMode(GL_MODELVIEW);
3484 glPushMatrix();
3485 glLoadIdentity();
3486 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3487 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3488 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3489 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3490 glPopMatrix();
3491 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3493 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3494 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3495 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3496 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3498 glEnable(GL_TEXTURE_GEN_S);
3499 glEnable(GL_TEXTURE_GEN_T);
3500 glEnable(GL_TEXTURE_GEN_R);
3501 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3503 break;
3505 case WINED3DTSS_TCI_SPHEREMAP:
3506 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3507 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3508 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3510 glEnable(GL_TEXTURE_GEN_S);
3511 glEnable(GL_TEXTURE_GEN_T);
3512 glDisable(GL_TEXTURE_GEN_R);
3513 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3515 break;
3517 default:
3518 FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3519 state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3520 glDisable(GL_TEXTURE_GEN_S);
3521 glDisable(GL_TEXTURE_GEN_T);
3522 glDisable(GL_TEXTURE_GEN_R);
3523 glDisable(GL_TEXTURE_GEN_Q);
3524 checkGLcall("Disable texgen.");
3526 break;
3529 /* Update the texture matrix. */
3530 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3531 transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3533 if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3535 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3536 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3537 * and do all the things linked to it
3538 * TODO: Tidy that up to reload only the arrays of the changed unit
3540 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3542 unload_tex_coords(gl_info);
3543 load_tex_coords(context, &device->strided_streams, &curVBO, state);
3547 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3549 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3550 const struct wined3d_shader *ps = state->pixel_shader;
3552 if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3554 /* The pixel shader has to know the luminance scale. Do a constants
3555 * update if it isn't scheduled anyway. */
3556 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3557 && !isStateDirty(context, STATE_PIXELSHADER))
3558 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3562 static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3564 const DWORD sampler = state_id - STATE_SAMPLER(0);
3565 const struct wined3d_texture *texture = state->textures[sampler];
3567 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3569 if(!texture) return;
3570 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3571 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3572 * scaling is reapplied or removed, the texture matrix has to be reapplied
3574 * The mapped stage is already active because the sampler() function below, which is part of the
3575 * misc pipeline
3577 if (sampler < MAX_TEXTURES)
3579 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3581 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3583 const struct wined3d_device *device = context->swapchain->device;
3585 if (texIsPow2)
3586 context->lastWasPow2Texture |= 1 << sampler;
3587 else
3588 context->lastWasPow2Texture &= ~(1 << sampler);
3590 transform_texture(context, state,
3591 STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3596 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3598 const struct wined3d_device *device = context->swapchain->device;
3599 DWORD sampler = state_id - STATE_SAMPLER(0);
3600 DWORD mapped_stage = device->texUnitMap[sampler];
3601 const struct wined3d_gl_info *gl_info = context->gl_info;
3602 union {
3603 float f;
3604 DWORD d;
3605 } tmpvalue;
3607 TRACE("Sampler: %d\n", sampler);
3608 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3609 * only has to bind textures and set the per texture states
3612 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3614 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3615 return;
3618 if (mapped_stage >= gl_info->limits.combined_samplers)
3620 return;
3622 context_active_texture(context, gl_info, mapped_stage);
3624 if (state->textures[sampler])
3626 struct wined3d_texture *texture = state->textures[sampler];
3627 BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3629 texture->texture_ops->texture_bind(texture, context, srgb);
3630 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3632 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3634 tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3635 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3636 GL_TEXTURE_LOD_BIAS_EXT,
3637 tmpvalue.f);
3638 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3641 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3643 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3645 /* If color keying is enabled update the alpha test, it
3646 * depends on the existence of a color key in stage 0. */
3647 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3651 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3652 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3653 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3655 else
3657 if (sampler < state->lowest_disabled_stage)
3659 /* TODO: What should I do with pixel shaders here ??? */
3660 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3662 /* If color keying is enabled update the alpha test, it
3663 * depends on the existence of a color key in stage 0. */
3664 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3666 } /* Otherwise tex_colorop disables the stage */
3667 context_bind_texture(context, GL_NONE, 0);
3671 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3673 const struct wined3d_device *device = context->swapchain->device;
3674 BOOL use_vshader = use_vs(state);
3675 BOOL use_pshader = use_ps(state);
3676 unsigned int i;
3678 if (use_pshader)
3680 if (!context->last_was_pshader)
3682 /* Former draw without a pixel shader, some samplers may be
3683 * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3684 * make sure to enable them. */
3685 for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3687 if (!isStateDirty(context, STATE_SAMPLER(i)))
3688 sampler(context, state, STATE_SAMPLER(i));
3690 context->last_was_pshader = TRUE;
3692 else
3694 /* Otherwise all samplers were activated by the code above in
3695 * earlier draws, or by sampler() if a different texture was
3696 * bound. I don't have to do anything. */
3699 else
3701 /* Disabled the pixel shader - color ops weren't applied while it was
3702 * enabled, so re-apply them. */
3703 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3705 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3706 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3708 context->last_was_pshader = FALSE;
3711 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
3713 device->shader_backend->shader_select(context, use_pshader, use_vshader);
3715 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader))
3716 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
3720 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3722 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3723 const struct wined3d_shader *ps = state->pixel_shader;
3725 if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3727 /* The pixel shader has to know the bump env matrix. Do a constants
3728 * update if it isn't scheduled anyway. */
3729 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3730 && !isStateDirty(context, STATE_PIXELSHADER))
3731 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3735 static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3737 /* This function is called by transform_view below if the view matrix was changed too
3739 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3740 * does not always update the world matrix, only on a switch between transformed
3741 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3742 * draw, but that should be rather rare and cheaper in total.
3744 glMatrixMode(GL_MODELVIEW);
3745 checkGLcall("glMatrixMode");
3747 if(context->last_was_rhw) {
3748 glLoadIdentity();
3749 checkGLcall("glLoadIdentity()");
3751 else
3753 /* In the general case, the view matrix is the identity matrix */
3754 if (context->swapchain->device->view_ident)
3756 glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3757 checkGLcall("glLoadMatrixf");
3759 else
3761 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3762 checkGLcall("glLoadMatrixf");
3763 glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3764 checkGLcall("glMultMatrixf");
3769 static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3771 UINT index = state_id - STATE_CLIPPLANE(0);
3772 GLdouble plane[4];
3774 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= context->gl_info->limits.clipplanes)
3775 return;
3777 glMatrixMode(GL_MODELVIEW);
3778 glPushMatrix();
3780 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3781 if (!use_vs(state))
3782 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3783 else
3784 /* with vertex shaders, clip planes are not transformed in direct3d,
3785 * in OpenGL they are still transformed by the model view.
3787 glLoadIdentity();
3789 plane[0] = state->clip_planes[index].x;
3790 plane[1] = state->clip_planes[index].y;
3791 plane[2] = state->clip_planes[index].z;
3792 plane[3] = state->clip_planes[index].w;
3794 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3795 plane[0], plane[1], plane[2], plane[3]);
3796 glClipPlane(GL_CLIP_PLANE0 + index, plane);
3797 checkGLcall("glClipPlane");
3799 glPopMatrix();
3802 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3804 UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3805 GLenum glMat;
3806 TRACE("Setting world matrix %d\n", matrix);
3808 if (matrix >= context->gl_info->limits.blends)
3810 WARN("Unsupported blend matrix set\n");
3811 return;
3814 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3815 return;
3817 /* GL_MODELVIEW0_ARB: 0x1700
3818 * GL_MODELVIEW1_ARB: 0x850a
3819 * GL_MODELVIEW2_ARB: 0x8722
3820 * GL_MODELVIEW3_ARB: 0x8723
3821 * etc
3822 * GL_MODELVIEW31_ARB: 0x873F
3824 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3825 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3827 glMatrixMode(glMat);
3828 checkGLcall("glMatrixMode(glMat)");
3830 /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3831 * matrices while gl uses only 2. To avoid weighting the view matrix
3832 * incorrectly it has to be multiplied into every GL modelview matrix. */
3833 if (context->swapchain->device->view_ident)
3835 glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3836 checkGLcall("glLoadMatrixf");
3838 else
3840 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3841 checkGLcall("glLoadMatrixf");
3842 glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3843 checkGLcall("glMultMatrixf");
3847 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3849 enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3850 static unsigned int once;
3852 if (f == WINED3D_VBF_DISABLE)
3853 return;
3855 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3856 else WARN("Vertex blend flags %#x not supported.\n", f);
3859 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3861 enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3862 struct wined3d_device *device = context->swapchain->device;
3863 const struct wined3d_gl_info *gl_info = context->gl_info;
3864 static unsigned int once;
3866 switch (val)
3868 case WINED3D_VBF_1WEIGHTS:
3869 case WINED3D_VBF_2WEIGHTS:
3870 case WINED3D_VBF_3WEIGHTS:
3871 glEnable(GL_VERTEX_BLEND_ARB);
3872 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3874 /* D3D adds one more matrix which has weight (1 - sum(weights)).
3875 * This is enabled at context creation with enabling
3876 * GL_WEIGHT_SUM_UNITY_ARB. */
3877 GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3879 if (!device->vertexBlendUsed)
3881 unsigned int i;
3882 for (i = 1; i < gl_info->limits.blends; ++i)
3884 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3885 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3887 device->vertexBlendUsed = TRUE;
3889 break;
3891 case WINED3D_VBF_TWEENING:
3892 case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3893 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3894 else WARN("Vertex blend flags %#x not supported.\n", val);
3895 /* Fall through. */
3896 case WINED3D_VBF_DISABLE:
3897 glDisable(GL_VERTEX_BLEND_ARB);
3898 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3899 break;
3903 static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3905 const struct wined3d_gl_info *gl_info = context->gl_info;
3906 const struct wined3d_light_info *light = NULL;
3907 unsigned int k;
3909 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3910 * NOTE: We have to reset the positions even if the light/plane is not currently
3911 * enabled, since the call to enable it will not reset the position.
3912 * NOTE2: Apparently texture transforms do NOT need reapplying
3915 glMatrixMode(GL_MODELVIEW);
3916 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3917 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3918 checkGLcall("glLoadMatrixf(...)");
3920 /* Reset lights. TODO: Call light apply func */
3921 for (k = 0; k < gl_info->limits.lights; ++k)
3923 if (!(light = state->lights[k]))
3924 continue;
3925 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3926 checkGLcall("glLightfv posn");
3927 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3928 checkGLcall("glLightfv dirn");
3931 /* Reset Clipping Planes */
3932 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3934 if (!isStateDirty(context, STATE_CLIPPLANE(k)))
3935 clipplane(context, state, STATE_CLIPPLANE(k));
3938 if(context->last_was_rhw) {
3939 glLoadIdentity();
3940 checkGLcall("glLoadIdentity()");
3941 /* No need to update the world matrix, the identity is fine */
3942 return;
3945 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3946 * No need to do it here if the state is scheduled for update. */
3947 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
3948 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
3950 /* Avoid looping over a number of matrices if the app never used the functionality */
3951 if (context->swapchain->device->vertexBlendUsed)
3953 for (k = 1; k < gl_info->limits.blends; ++k)
3955 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
3956 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
3961 static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3963 glMatrixMode(GL_PROJECTION);
3964 checkGLcall("glMatrixMode(GL_PROJECTION)");
3966 /* There are a couple of additional things we have to take into account
3967 * here besides the projection transformation itself:
3968 * - We need to flip along the y-axis in case of offscreen rendering.
3969 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
3970 * - D3D coordinates refer to pixel centers while GL coordinates refer
3971 * to pixel corners.
3972 * - D3D has a top-left filling convention. We need to maintain this
3973 * even after the y-flip mentioned above.
3974 * In order to handle the last two points, we translate by
3975 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
3976 * translating slightly less than half a pixel. We want the difference to
3977 * be large enough that it doesn't get lost due to rounding inside the
3978 * driver, but small enough to prevent it from interfering with any
3979 * anti-aliasing. */
3981 if (context->last_was_rhw)
3983 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
3984 double x = state->viewport.x;
3985 double y = state->viewport.y;
3986 double w = state->viewport.width;
3987 double h = state->viewport.height;
3988 double x_scale = 2.0 / w;
3989 double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
3990 double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
3991 double y_offset = context->render_offscreen
3992 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
3993 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
3994 const GLdouble projection[] =
3996 x_scale, 0.0, 0.0, 0.0,
3997 0.0, y_scale, 0.0, 0.0,
3998 0.0, 0.0, 2.0, 0.0,
3999 x_offset, y_offset, -1.0, 1.0,
4002 glLoadMatrixd(projection);
4003 checkGLcall("glLoadMatrixd");
4005 else
4007 double y_scale = context->render_offscreen ? -1.0 : 1.0;
4008 double x_offset = (63.0 / 64.0) / state->viewport.width;
4009 double y_offset = context->render_offscreen
4010 ? (63.0 / 64.0) / state->viewport.height
4011 : -(63.0 / 64.0) / state->viewport.height;
4012 const GLdouble projection[] =
4014 1.0, 0.0, 0.0, 0.0,
4015 0.0, y_scale, 0.0, 0.0,
4016 0.0, 0.0, 2.0, 0.0,
4017 x_offset, y_offset, -1.0, 1.0,
4020 glLoadMatrixd(projection);
4021 checkGLcall("glLoadMatrixd");
4023 glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4024 checkGLcall("glLoadMatrixf");
4028 /* This should match any arrays loaded in load_vertex_data.
4029 * TODO: Only load / unload arrays if we have to. */
4030 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4032 glDisableClientState(GL_VERTEX_ARRAY);
4033 glDisableClientState(GL_NORMAL_ARRAY);
4034 glDisableClientState(GL_COLOR_ARRAY);
4035 if (gl_info->supported[EXT_SECONDARY_COLOR])
4037 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4039 if (gl_info->supported[ARB_VERTEX_BLEND])
4041 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4043 unload_tex_coords(gl_info);
4046 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4048 const struct wined3d_gl_info *gl_info = context->gl_info;
4050 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4051 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4053 context->numbered_array_mask &= ~(1 << i);
4056 /* This should match any arrays loaded in loadNumberedArrays
4057 * TODO: Only load / unload arrays if we have to. */
4058 static void unload_numbered_arrays(struct wined3d_context *context)
4060 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4061 int i;
4063 for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4064 unload_numbered_array(context, i);
4068 static void load_numbered_arrays(struct wined3d_context *context,
4069 const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4071 struct wined3d_device *device = context->swapchain->device;
4072 const struct wined3d_gl_info *gl_info = context->gl_info;
4073 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4074 int i;
4076 /* Default to no instancing */
4077 device->instancedDraw = FALSE;
4079 for (i = 0; i < MAX_ATTRIBS; i++)
4081 const struct wined3d_stream_state *stream;
4083 if (!(stream_info->use_map & (1 << i)))
4085 if (context->numbered_array_mask & (1 << i))
4086 unload_numbered_array(context, i);
4087 if (state->vertex_shader->reg_maps.input_registers & (1 << i))
4088 GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
4089 continue;
4092 stream = &state->streams[stream_info->elements[i].stream_idx];
4094 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4095 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4097 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4098 device->instancedDraw = TRUE;
4099 continue;
4102 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4104 if (stream_info->elements[i].stride)
4106 if (curVBO != stream_info->elements[i].data.buffer_object)
4108 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4109 checkGLcall("glBindBufferARB");
4110 curVBO = stream_info->elements[i].data.buffer_object;
4112 /* Use the VBO to find out if a vertex buffer exists, not the vb
4113 * pointer. vb can point to a user pointer data blob. In that case
4114 * curVBO will be 0. If there is a vertex buffer but no vbo we
4115 * won't be load converted attributes anyway. */
4116 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4117 stream_info->elements[i].format->gl_vtx_type,
4118 stream_info->elements[i].format->gl_normalized,
4119 stream_info->elements[i].stride, stream_info->elements[i].data.addr
4120 + state->load_base_vertex_index * stream_info->elements[i].stride));
4122 if (!(context->numbered_array_mask & (1 << i)))
4124 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4125 context->numbered_array_mask |= (1 << i);
4128 else
4130 /* Stride = 0 means always the same values.
4131 * glVertexAttribPointerARB doesn't do that. Instead disable the
4132 * pointer and set up the attribute statically. But we have to
4133 * figure out the system memory address. */
4134 const BYTE *ptr = stream_info->elements[i].data.addr;
4135 if (stream_info->elements[i].data.buffer_object)
4137 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4140 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4142 switch (stream_info->elements[i].format->id)
4144 case WINED3DFMT_R32_FLOAT:
4145 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4146 break;
4147 case WINED3DFMT_R32G32_FLOAT:
4148 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4149 break;
4150 case WINED3DFMT_R32G32B32_FLOAT:
4151 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4152 break;
4153 case WINED3DFMT_R32G32B32A32_FLOAT:
4154 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4155 break;
4157 case WINED3DFMT_R8G8B8A8_UINT:
4158 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4159 break;
4160 case WINED3DFMT_B8G8R8A8_UNORM:
4161 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4163 const DWORD *src = (const DWORD *)ptr;
4164 DWORD c = *src & 0xff00ff00;
4165 c |= (*src & 0xff0000) >> 16;
4166 c |= (*src & 0xff) << 16;
4167 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4168 break;
4170 /* else fallthrough */
4171 case WINED3DFMT_R8G8B8A8_UNORM:
4172 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4173 break;
4175 case WINED3DFMT_R16G16_SINT:
4176 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4177 break;
4178 case WINED3DFMT_R16G16B16A16_SINT:
4179 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4180 break;
4182 case WINED3DFMT_R16G16_SNORM:
4184 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4185 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4186 break;
4188 case WINED3DFMT_R16G16_UNORM:
4190 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4191 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4192 break;
4194 case WINED3DFMT_R16G16B16A16_SNORM:
4195 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4196 break;
4197 case WINED3DFMT_R16G16B16A16_UNORM:
4198 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4199 break;
4201 case WINED3DFMT_R10G10B10A2_UINT:
4202 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4203 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4204 break;
4205 case WINED3DFMT_R10G10B10A2_SNORM:
4206 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4207 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4208 break;
4210 case WINED3DFMT_R16G16_FLOAT:
4211 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4212 * byte float according to the IEEE standard
4214 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4215 break;
4216 case WINED3DFMT_R16G16B16A16_FLOAT:
4217 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4218 break;
4220 default:
4221 ERR("Unexpected declaration in stride 0 attributes\n");
4222 break;
4227 checkGLcall("Loading numbered arrays");
4230 static void load_vertex_data(const struct wined3d_context *context,
4231 const struct wined3d_stream_info *si, const struct wined3d_state *state)
4233 struct wined3d_device *device = context->swapchain->device;
4234 const struct wined3d_gl_info *gl_info = context->gl_info;
4235 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4236 const struct wined3d_stream_info_element *e;
4238 TRACE("Using fast vertex array code\n");
4240 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4241 device->instancedDraw = FALSE;
4243 /* Blend Data ---------------------------------------------- */
4244 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4245 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4247 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4249 if (gl_info->supported[ARB_VERTEX_BLEND])
4251 TRACE("Blend %u %p %u\n", e->format->component_count,
4252 e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4254 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4255 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4257 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4259 if (curVBO != e->data.buffer_object)
4261 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4262 checkGLcall("glBindBufferARB");
4263 curVBO = e->data.buffer_object;
4266 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4267 e->format->gl_vtx_format,
4268 e->format->gl_vtx_type,
4269 e->stride,
4270 e->data.addr + state->load_base_vertex_index * e->stride);
4271 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4272 e->data.addr + state->load_base_vertex_index * e->stride));
4274 checkGLcall("glWeightPointerARB");
4276 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4278 static BOOL warned;
4279 if (!warned)
4281 FIXME("blendMatrixIndices support\n");
4282 warned = TRUE;
4285 } else {
4286 /* TODO: support blends in drawStridedSlow
4287 * No need to write a FIXME here, this is done after the general vertex decl decoding
4289 WARN("unsupported blending in openGl\n");
4292 else
4294 if (gl_info->supported[ARB_VERTEX_BLEND])
4296 static const GLbyte one = 1;
4297 GL_EXTCALL(glWeightbvARB(1, &one));
4298 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4302 /* Point Size ----------------------------------------------*/
4303 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4305 /* no such functionality in the fixed function GL pipeline */
4306 TRACE("Cannot change ptSize here in openGl\n");
4307 /* TODO: Implement this function in using shaders if they are available */
4310 /* Vertex Pointers -----------------------------------------*/
4311 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4313 e = &si->elements[WINED3D_FFP_POSITION];
4315 if (curVBO != e->data.buffer_object)
4317 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4318 checkGLcall("glBindBufferARB");
4319 curVBO = e->data.buffer_object;
4322 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4323 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4324 e->data.addr + state->load_base_vertex_index * e->stride);
4325 glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4326 e->data.addr + state->load_base_vertex_index * e->stride);
4327 checkGLcall("glVertexPointer(...)");
4328 glEnableClientState(GL_VERTEX_ARRAY);
4329 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4332 /* Normals -------------------------------------------------*/
4333 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4335 e = &si->elements[WINED3D_FFP_NORMAL];
4337 if (curVBO != e->data.buffer_object)
4339 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4340 checkGLcall("glBindBufferARB");
4341 curVBO = e->data.buffer_object;
4344 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4345 e->data.addr + state->load_base_vertex_index * e->stride);
4346 glNormalPointer(e->format->gl_vtx_type, e->stride,
4347 e->data.addr + state->load_base_vertex_index * e->stride);
4348 checkGLcall("glNormalPointer(...)");
4349 glEnableClientState(GL_NORMAL_ARRAY);
4350 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4352 } else {
4353 glNormal3f(0, 0, 0);
4354 checkGLcall("glNormal3f(0, 0, 0)");
4357 /* Diffuse Colour --------------------------------------------*/
4358 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4360 e = &si->elements[WINED3D_FFP_DIFFUSE];
4362 if (curVBO != e->data.buffer_object)
4364 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4365 checkGLcall("glBindBufferARB");
4366 curVBO = e->data.buffer_object;
4369 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4370 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4371 e->data.addr + state->load_base_vertex_index * e->stride);
4372 glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4373 e->data.addr + state->load_base_vertex_index * e->stride);
4374 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4375 glEnableClientState(GL_COLOR_ARRAY);
4376 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4378 } else {
4379 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4380 checkGLcall("glColor4f(1, 1, 1, 1)");
4383 /* Specular Colour ------------------------------------------*/
4384 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4386 TRACE("setting specular colour\n");
4388 e = &si->elements[WINED3D_FFP_SPECULAR];
4390 if (gl_info->supported[EXT_SECONDARY_COLOR])
4392 GLenum type = e->format->gl_vtx_type;
4393 GLint format = e->format->gl_vtx_format;
4395 if (curVBO != e->data.buffer_object)
4397 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4398 checkGLcall("glBindBufferARB");
4399 curVBO = e->data.buffer_object;
4402 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4404 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4405 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4406 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4407 * 4 component secondary colors use it
4409 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4410 e->data.addr + state->load_base_vertex_index * e->stride);
4411 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4412 e->data.addr + state->load_base_vertex_index * e->stride));
4413 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4415 else
4417 switch(type)
4419 case GL_UNSIGNED_BYTE:
4420 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4421 e->data.addr + state->load_base_vertex_index * e->stride);
4422 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4423 e->data.addr + state->load_base_vertex_index * e->stride));
4424 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4425 break;
4427 default:
4428 FIXME("Add 4 component specular color pointers for type %x\n", type);
4429 /* Make sure that the right color component is dropped */
4430 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4431 e->data.addr + state->load_base_vertex_index * e->stride);
4432 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4433 e->data.addr + state->load_base_vertex_index * e->stride));
4434 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4437 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4438 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4440 else
4442 WARN("Specular colour is not supported in this GL implementation.\n");
4445 else
4447 if (gl_info->supported[EXT_SECONDARY_COLOR])
4449 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4450 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4452 else
4454 WARN("Specular colour is not supported in this GL implementation.\n");
4458 /* Texture coords -------------------------------------------*/
4459 load_tex_coords(context, si, &curVBO, state);
4462 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4464 const struct wined3d_device *device = context->swapchain->device;
4465 BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4466 BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4468 if (isStateDirty(context, STATE_VDECL)) return;
4469 if (context->numberedArraysLoaded && !load_numbered)
4471 unload_numbered_arrays(context);
4472 context->numberedArraysLoaded = FALSE;
4473 context->numbered_array_mask = 0;
4475 else if (context->namedArraysLoaded)
4477 unload_vertex_data(context->gl_info);
4478 context->namedArraysLoaded = FALSE;
4481 if (load_numbered)
4483 TRACE("Loading numbered arrays\n");
4484 load_numbered_arrays(context, &device->strided_streams, state);
4485 context->numberedArraysLoaded = TRUE;
4487 else if (load_named)
4489 TRACE("Loading vertex data\n");
4490 load_vertex_data(context, &device->strided_streams, state);
4491 context->namedArraysLoaded = TRUE;
4495 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4497 if (isStateDirty(context, STATE_STREAMSRC))
4498 return;
4499 streamsrc(context, state, STATE_STREAMSRC);
4502 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4504 const struct wined3d_device *device = context->swapchain->device;
4505 const struct wined3d_gl_info *gl_info = context->gl_info;
4506 BOOL useVertexShaderFunction = use_vs(state);
4507 BOOL usePixelShaderFunction = use_ps(state);
4508 BOOL updateFog = FALSE;
4509 BOOL transformed;
4510 BOOL wasrhw = context->last_was_rhw;
4511 unsigned int i;
4513 transformed = device->strided_streams.position_transformed;
4514 if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4515 updateFog = TRUE;
4517 context->last_was_rhw = transformed;
4519 /* Don't have to apply the matrices when vertex shaders are used. When
4520 * vshaders are turned off this function will be called again anyway to
4521 * make sure they're properly set. */
4522 if (!useVertexShaderFunction)
4524 /* TODO: Move this mainly to the viewport state and only apply when
4525 * the vp has changed or transformed / untransformed was switched. */
4526 if (wasrhw != context->last_was_rhw
4527 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4528 && !isStateDirty(context, STATE_VIEWPORT))
4529 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4530 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4531 * mode.
4533 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4534 * this check will fail and the matrix not applied again. This is OK because a simple
4535 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4536 * needs of the vertex declaration.
4538 * World and view matrix go into the same gl matrix, so only apply them when neither is
4539 * dirty
4541 if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4542 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4543 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4544 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4545 state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4546 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4547 state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4549 if (context->last_was_vshader)
4551 updateFog = TRUE;
4553 if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4554 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4556 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4558 clipplane(context, state, STATE_CLIPPLANE(i));
4561 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4562 state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4564 else
4566 if(!context->last_was_vshader) {
4567 static BOOL warned = FALSE;
4568 if(!device->vs_clipping) {
4569 /* Disable all clip planes to get defined results on all drivers. See comment in the
4570 * state_clipping state handler
4572 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4574 glDisable(GL_CLIP_PLANE0 + i);
4575 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4578 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4580 FIXME("Clipping not supported with vertex shaders\n");
4581 warned = TRUE;
4584 if (wasrhw)
4586 /* Apply the transform matrices when switching from rhw
4587 * drawing to vertex shaders. Vertex shaders themselves do
4588 * not need it, but the matrices are not reapplied
4589 * automatically when switching back from vertex shaders to
4590 * fixed function processing. So make sure we leave the fixed
4591 * function vertex processing states back in a sane state
4592 * before switching to shaders. */
4593 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4594 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4595 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4596 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4598 updateFog = TRUE;
4600 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4601 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4602 * device->vs_clipping is false.
4604 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4606 clipplane(context, state, STATE_CLIPPLANE(i));
4611 /* Vertex and pixel shaders are applied together, so let the last dirty
4612 * state do the application. */
4613 if (!isStateDirty(context, STATE_PIXELSHADER))
4615 device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4617 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)
4618 && (useVertexShaderFunction || usePixelShaderFunction))
4619 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4622 context->last_was_vshader = useVertexShaderFunction;
4624 if (updateFog)
4625 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4627 if (!useVertexShaderFunction)
4629 unsigned int i;
4631 for (i = 0; i < MAX_TEXTURES; ++i)
4633 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4634 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4638 if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4639 state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4642 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4644 const struct wined3d_surface *target = state->fb->render_targets[0];
4645 struct wined3d_viewport vp = state->viewport;
4647 if (vp.width > target->resource.width)
4648 vp.width = target->resource.width;
4649 if (vp.height > target->resource.height)
4650 vp.height = target->resource.height;
4652 glDepthRange(vp.min_z, vp.max_z);
4653 checkGLcall("glDepthRange");
4654 /* Note: GL requires lower left, DirectX supplies upper left. This is
4655 * reversed when using offscreen rendering. */
4656 if (context->render_offscreen)
4658 glViewport(vp.x, vp.y, vp.width, vp.height);
4660 else
4662 UINT width, height;
4664 target->get_drawable_size(context, &width, &height);
4665 glViewport(vp.x, (height - (vp.y + vp.height)),
4666 vp.width, vp.height);
4669 checkGLcall("glViewport");
4672 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4674 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4675 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4676 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4677 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4678 /* Update the position fixup. */
4679 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
4680 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4683 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4685 UINT Index = state_id - STATE_ACTIVELIGHT(0);
4686 const struct wined3d_light_info *lightInfo = state->lights[Index];
4688 if (!lightInfo)
4690 glDisable(GL_LIGHT0 + Index);
4691 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4693 else
4695 float quad_att;
4696 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4698 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4699 glMatrixMode(GL_MODELVIEW);
4700 glPushMatrix();
4701 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4703 /* Diffuse: */
4704 colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4705 colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4706 colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4707 colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4708 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4709 checkGLcall("glLightfv");
4711 /* Specular */
4712 colRGBA[0] = lightInfo->OriginalParms.specular.r;
4713 colRGBA[1] = lightInfo->OriginalParms.specular.g;
4714 colRGBA[2] = lightInfo->OriginalParms.specular.b;
4715 colRGBA[3] = lightInfo->OriginalParms.specular.a;
4716 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4717 checkGLcall("glLightfv");
4719 /* Ambient */
4720 colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4721 colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4722 colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4723 colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4724 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4725 checkGLcall("glLightfv");
4727 if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4728 quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4729 else
4730 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4732 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4733 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4734 * Attenuation0 to NaN and crashes in the gl lib
4737 switch (lightInfo->OriginalParms.type)
4739 case WINED3D_LIGHT_POINT:
4740 /* Position */
4741 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4742 checkGLcall("glLightfv");
4743 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4744 checkGLcall("glLightf");
4745 /* Attenuation - Are these right? guessing... */
4746 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4747 checkGLcall("glLightf");
4748 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4749 checkGLcall("glLightf");
4750 if (quad_att < lightInfo->OriginalParms.attenuation2)
4751 quad_att = lightInfo->OriginalParms.attenuation2;
4752 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4753 checkGLcall("glLightf");
4754 /* FIXME: Range */
4755 break;
4757 case WINED3D_LIGHT_SPOT:
4758 /* Position */
4759 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4760 checkGLcall("glLightfv");
4761 /* Direction */
4762 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4763 checkGLcall("glLightfv");
4764 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4765 checkGLcall("glLightf");
4766 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4767 checkGLcall("glLightf");
4768 /* Attenuation - Are these right? guessing... */
4769 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4770 checkGLcall("glLightf");
4771 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4772 checkGLcall("glLightf");
4773 if (quad_att < lightInfo->OriginalParms.attenuation2)
4774 quad_att = lightInfo->OriginalParms.attenuation2;
4775 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4776 checkGLcall("glLightf");
4777 /* FIXME: Range */
4778 break;
4780 case WINED3D_LIGHT_DIRECTIONAL:
4781 /* Direction */
4782 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4783 checkGLcall("glLightfv");
4784 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4785 checkGLcall("glLightf");
4786 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4787 checkGLcall("glLightf");
4788 break;
4790 default:
4791 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4794 /* Restore the modelview matrix */
4795 glPopMatrix();
4797 glEnable(GL_LIGHT0 + Index);
4798 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4802 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4804 const RECT *r = &state->scissor_rect;
4806 /* Warning: glScissor uses window coordinates, not viewport coordinates,
4807 * so our viewport correction does not apply. Warning2: Even in windowed
4808 * mode the coords are relative to the window, not the screen. */
4809 TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4811 if (context->render_offscreen)
4813 glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4815 else
4817 const struct wined3d_surface *target = state->fb->render_targets[0];
4818 UINT height;
4819 UINT width;
4821 target->get_drawable_size(context, &width, &height);
4822 glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4824 checkGLcall("glScissor");
4827 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4829 const struct wined3d_stream_info *stream_info = &context->swapchain->device->strided_streams;
4830 const struct wined3d_gl_info *gl_info = context->gl_info;
4832 if (state->user_stream || !state->index_buffer || !stream_info->all_vbo)
4834 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4836 else
4838 struct wined3d_buffer *ib = state->index_buffer;
4839 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4843 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4845 if (context->render_offscreen)
4847 glFrontFace(GL_CCW);
4848 checkGLcall("glFrontFace(GL_CCW)");
4849 } else {
4850 glFrontFace(GL_CW);
4851 checkGLcall("glFrontFace(GL_CW)");
4855 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4857 static BOOL warned;
4859 if (!warned)
4861 WARN("Point sprite coordinate origin switching not supported.\n");
4862 warned = TRUE;
4866 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4868 const struct wined3d_gl_info *gl_info = context->gl_info;
4869 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4871 if (glPointParameteri)
4873 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin);
4874 checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4876 else if (gl_info->supported[NV_POINT_SPRITE])
4878 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4879 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4883 const struct StateEntryTemplate misc_state_template[] = {
4884 { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4885 { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4886 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4887 { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4888 { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4889 { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4890 { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4891 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4892 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4893 { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4894 { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
4895 { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
4896 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4897 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4898 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4899 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4901 /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4902 * vshader loadings are untied from each other
4904 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4905 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4906 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4907 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4908 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4909 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4910 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4911 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4912 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4913 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4914 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4915 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4916 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4917 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4918 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4919 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4920 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4921 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4922 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4923 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4924 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4925 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4926 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4927 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4928 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4929 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4930 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4931 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4932 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4933 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4934 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4935 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4936 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4937 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4938 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4939 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4940 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4941 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4942 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4943 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4944 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4945 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4946 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4947 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4948 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4949 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4950 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4951 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4952 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4953 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4955 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
4956 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
4957 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
4958 { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
4959 { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
4960 { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
4961 { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
4962 { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
4963 { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
4964 { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
4965 { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
4966 { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
4967 { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
4968 { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
4969 { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
4970 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
4971 { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4972 { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4973 { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4974 { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
4975 { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
4976 { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
4977 { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
4978 { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
4979 { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
4980 { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
4981 { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
4982 { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
4983 { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
4984 { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
4985 { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
4986 { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4987 { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4988 { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4989 { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4990 { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4991 { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4992 { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4993 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
4994 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
4995 { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4996 { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4997 { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4998 { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4999 { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5000 { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5001 { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5003 { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5004 { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5005 { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5006 { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5007 { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5008 { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5009 { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5010 { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5011 { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5012 { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5013 { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5014 { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5015 { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5016 { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5017 { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5018 { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5019 { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5020 { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5021 { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5022 { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5023 { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5024 { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5025 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5026 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5027 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5028 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5029 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5030 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
5031 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5032 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5033 { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5034 { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5035 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5036 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5037 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5038 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5039 { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5040 { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5042 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5044 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5045 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5046 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5047 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5048 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5050 { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5051 /* Samplers */
5052 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5053 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5054 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5055 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5056 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5057 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5058 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5059 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5060 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5061 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5062 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5063 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5064 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5065 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5066 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5067 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5068 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5069 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5070 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5071 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5072 { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
5073 { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
5074 { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
5075 { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
5076 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5079 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5080 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5081 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5082 { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5083 { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5084 /* Clip planes */
5085 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5086 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5087 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5088 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5089 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5090 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5091 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5092 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5093 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5094 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5095 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5096 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5097 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5098 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5099 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5100 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5101 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5102 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5103 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5104 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5105 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5106 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5107 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5108 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5109 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5110 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5111 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5112 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5113 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5114 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5115 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5116 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5117 /* Lights */
5118 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5119 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5120 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5121 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5122 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5123 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5124 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5125 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5126 /* Viewport */
5127 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5128 /* Transform states follow */
5129 { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5130 { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5131 { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5132 { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5133 { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5134 { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5135 { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5136 { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5137 { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5138 { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5139 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5140 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5141 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5142 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5143 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5144 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5145 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5146 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5147 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5148 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5149 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5150 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5151 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5152 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5153 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5154 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5155 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5156 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5157 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5158 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5159 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5160 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5161 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5162 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5163 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5164 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5165 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5166 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5167 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5168 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5169 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5170 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5171 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5172 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5173 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5174 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5175 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5176 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5177 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5178 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5179 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5180 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5181 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5182 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5183 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5184 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5185 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5186 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5187 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5188 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5189 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5190 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5191 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5192 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5193 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5194 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5195 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5396 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5397 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5398 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5399 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5400 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5401 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5402 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5403 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5405 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5406 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5407 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5411 /* Fog */
5412 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5413 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5414 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5415 { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5416 { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5417 { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5418 { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5419 { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5420 { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5421 { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5422 { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5423 { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5424 { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5425 { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5426 { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5427 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5428 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5429 { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5430 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5431 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5432 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5433 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5434 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5435 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5436 { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5437 { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5438 { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5439 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5440 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5441 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5442 { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5443 { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5445 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5446 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5447 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5449 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5450 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5451 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5452 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5453 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5454 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5455 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5456 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5457 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5458 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5459 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5460 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5461 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5462 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5463 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5464 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5465 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5466 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5467 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5468 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5469 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5470 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5471 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5472 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5473 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5476 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5477 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5478 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5479 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5480 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5481 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5482 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5483 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5484 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5485 { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5486 { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5487 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5488 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5489 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5490 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5491 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5492 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5493 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5494 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5495 { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5496 { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5497 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5498 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5499 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5500 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5501 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5502 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5503 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5504 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5505 { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5506 { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5507 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5508 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5509 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5510 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5511 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5512 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5513 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5514 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5515 { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5516 { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5517 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5518 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5519 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5520 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5521 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5522 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5523 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5524 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5525 { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5526 { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5527 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5528 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5529 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5530 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5531 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5532 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5533 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5534 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5535 { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5536 { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5537 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5538 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5539 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5540 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5541 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5542 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5543 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5544 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5545 { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5546 { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5547 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5548 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5549 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5550 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5551 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5552 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5553 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5554 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5555 { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5556 { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5557 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5558 { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5559 { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5560 { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5561 { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5562 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5563 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5564 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5565 { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5566 { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5567 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5568 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5569 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5570 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5571 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5572 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5573 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5574 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5575 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5578 /* Context activation and GL locking are done by the caller. */
5579 static void ffp_enable(BOOL enable) {}
5581 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5583 caps->PrimitiveMiscCaps = 0;
5584 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5585 | WINED3DTEXOPCAPS_ADDSIGNED
5586 | WINED3DTEXOPCAPS_ADDSIGNED2X
5587 | WINED3DTEXOPCAPS_MODULATE
5588 | WINED3DTEXOPCAPS_MODULATE2X
5589 | WINED3DTEXOPCAPS_MODULATE4X
5590 | WINED3DTEXOPCAPS_SELECTARG1
5591 | WINED3DTEXOPCAPS_SELECTARG2
5592 | WINED3DTEXOPCAPS_DISABLE;
5594 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5595 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5596 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5598 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5599 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5600 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5601 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5602 | WINED3DTEXOPCAPS_LERP
5603 | WINED3DTEXOPCAPS_SUBTRACT;
5605 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5606 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5608 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5609 | WINED3DTEXOPCAPS_MULTIPLYADD
5610 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5611 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5612 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5614 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5615 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5617 caps->MaxTextureBlendStages = gl_info->limits.textures;
5618 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5621 static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; }
5622 static void ffp_fragment_free(struct wined3d_device *device) {}
5623 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5625 if (TRACE_ON(d3d))
5627 TRACE("Checking support for fixup:\n");
5628 dump_color_fixup_desc(fixup);
5631 /* We only support identity conversions. */
5632 if (is_identity_fixup(fixup))
5634 TRACE("[OK]\n");
5635 return TRUE;
5638 TRACE("[FAILED]\n");
5639 return FALSE;
5642 const struct fragment_pipeline ffp_fragment_pipeline = {
5643 ffp_enable,
5644 ffp_fragment_get_caps,
5645 ffp_fragment_alloc,
5646 ffp_fragment_free,
5647 ffp_color_fixup_supported,
5648 ffp_fragmentstate_template,
5649 FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5652 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5654 unsigned int i;
5655 for(i = 0; funcs[i]; i++);
5656 return i;
5659 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5661 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5662 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5665 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5667 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5668 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5669 context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5672 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5674 unsigned int start, last, i;
5676 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5677 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5678 for (i = start; i <= last; ++i)
5680 state_table[i].representative = 0;
5681 state_table[i].apply = state_undefined;
5684 start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
5685 last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5686 for (i = start; i <= last; ++i)
5688 state_table[i].representative = 0;
5689 state_table[i].apply = state_undefined;
5692 start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5693 last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5694 for (i = start; i <= last; ++i)
5696 state_table[i].representative = 0;
5697 state_table[i].apply = state_undefined;
5701 static void validate_state_table(struct StateEntry *state_table)
5703 static const struct
5705 DWORD first;
5706 DWORD last;
5708 rs_holes[] =
5710 { 1, 1},
5711 { 3, 3},
5712 { 17, 18},
5713 { 21, 21},
5714 { 42, 45},
5715 { 47, 47},
5716 { 61, 127},
5717 {149, 150},
5718 {169, 169},
5719 {177, 177},
5720 {196, 197},
5721 { 0, 0},
5723 static const DWORD simple_states[] =
5725 STATE_MATERIAL,
5726 STATE_VDECL,
5727 STATE_STREAMSRC,
5728 STATE_INDEXBUFFER,
5729 STATE_VERTEXSHADERCONSTANT,
5730 STATE_PIXELSHADERCONSTANT,
5731 STATE_VSHADER,
5732 STATE_PIXELSHADER,
5733 STATE_VIEWPORT,
5734 STATE_SCISSORRECT,
5735 STATE_FRONTFACE,
5736 STATE_POINTSPRITECOORDORIGIN,
5737 STATE_BASEVERTEXINDEX,
5738 STATE_FRAMEBUFFER
5740 unsigned int i, current;
5742 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5744 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5746 if (!state_table[i].representative)
5747 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5749 else if (state_table[i].representative)
5750 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5752 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5755 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5757 if (!state_table[simple_states[i]].representative)
5758 ERR("State %s (%#x) should have a representative.\n",
5759 debug_d3dstate(simple_states[i]), simple_states[i]);
5762 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5764 DWORD rep = state_table[i].representative;
5765 if (rep)
5767 if (state_table[rep].representative != rep)
5769 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5770 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5771 state_table[i].representative = 0;
5774 if (rep != i)
5776 if (state_table[i].apply)
5777 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5779 else if (!state_table[i].apply)
5781 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5787 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5788 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5789 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5791 unsigned int i, type, handlers;
5792 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5793 const struct StateEntryTemplate *cur;
5794 BOOL set[STATE_HIGHEST + 1];
5796 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5798 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5799 StateTable[i].representative = 0;
5800 StateTable[i].apply = state_undefined;
5803 for(type = 0; type < 3; type++) {
5804 /* This switch decides the order in which the states are applied */
5805 switch(type) {
5806 case 0: cur = misc; break;
5807 case 1: cur = fragment->states; break;
5808 case 2: cur = vertex; break;
5809 default: cur = NULL; /* Stupid compiler */
5811 if(!cur) continue;
5813 /* GL extension filtering should not prevent multiple handlers being applied from different
5814 * pipeline parts
5816 memset(set, 0, sizeof(set));
5818 for(i = 0; cur[i].state; i++) {
5819 APPLYSTATEFUNC *funcs_array;
5821 /* Only use the first matching state with the available extension from one template.
5822 * e.g.
5823 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5824 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5826 * if GL_XYZ_fancy is supported, ignore the 2nd line
5828 if(set[cur[i].state]) continue;
5829 /* Skip state lines depending on unsupported extensions */
5830 if (!gl_info->supported[cur[i].extension]) continue;
5831 set[cur[i].state] = TRUE;
5832 /* In some cases having an extension means that nothing has to be
5833 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5834 * supported, the texture coordinate fixup can be ignored. If the
5835 * apply function is used, mark the state set(done above) to prevent
5836 * applying later lines, but do not record anything in the state
5837 * table
5839 if (!cur[i].content.representative) continue;
5841 handlers = num_handlers(multistate_funcs[cur[i].state]);
5842 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5843 switch(handlers) {
5844 case 0:
5845 StateTable[cur[i].state].apply = cur[i].content.apply;
5846 break;
5847 case 1:
5848 StateTable[cur[i].state].apply = multistate_apply_2;
5849 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5851 sizeof(**dev_multistate_funcs) * 2);
5852 if (!dev_multistate_funcs[cur[i].state]) {
5853 goto out_of_mem;
5856 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5857 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5858 break;
5859 case 2:
5860 StateTable[cur[i].state].apply = multistate_apply_3;
5861 funcs_array = HeapReAlloc(GetProcessHeap(),
5863 dev_multistate_funcs[cur[i].state],
5864 sizeof(**dev_multistate_funcs) * 3);
5865 if (!funcs_array) {
5866 goto out_of_mem;
5869 dev_multistate_funcs[cur[i].state] = funcs_array;
5870 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5871 break;
5872 default:
5873 ERR("Unexpected amount of state handlers for state %u: %u\n",
5874 cur[i].state, handlers + 1);
5877 if(StateTable[cur[i].state].representative &&
5878 StateTable[cur[i].state].representative != cur[i].content.representative) {
5879 FIXME("State %u has different representatives in different pipeline parts\n",
5880 cur[i].state);
5882 StateTable[cur[i].state].representative = cur[i].content.representative;
5886 prune_invalid_states(StateTable, gl_info);
5887 validate_state_table(StateTable);
5889 return WINED3D_OK;
5891 out_of_mem:
5892 for (i = 0; i <= STATE_HIGHEST; ++i) {
5893 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5896 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5898 return E_OUTOFMEMORY;