msxml3: Properly escape character data in text nodes.
[wine/multimedia.git] / dlls / wined3d / state.c
blob697432176ef4a39d5b944c0536c6d0a7df566c1b
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 <stdio.h>
30 #ifdef HAVE_FLOAT_H
31 # include <float.h>
32 #endif
33 #include "wined3d_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
36 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
38 /* GL locking for state handlers is done by the caller. */
40 static void state_undefined(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
42 ERR("Undefined state.\n");
45 static void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
47 TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state_id));
50 static void state_fillmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
52 enum wined3d_fill_mode mode = state->render_states[WINED3D_RS_FILLMODE];
54 switch (mode)
56 case WINED3D_FILL_POINT:
57 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
58 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
59 break;
60 case WINED3D_FILL_WIREFRAME:
61 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
62 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
63 break;
64 case WINED3D_FILL_SOLID:
65 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
66 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
67 break;
68 default:
69 FIXME("Unrecognized fill mode %#x.\n", mode);
73 static void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
75 /* Lighting is not enabled if transformed vertices are drawn, but lighting
76 * does not affect the stream sources, so it is not grouped for
77 * performance reasons. This state reads the decoded vertex declaration,
78 * so if it is dirty don't do anything. The vertex declaration applying
79 * function calls this function for updating. */
80 if (isStateDirty(context, STATE_VDECL))
81 return;
83 if (state->render_states[WINED3D_RS_LIGHTING]
84 && !context->swapchain->device->strided_streams.position_transformed)
86 glEnable(GL_LIGHTING);
87 checkGLcall("glEnable GL_LIGHTING");
88 } else {
89 glDisable(GL_LIGHTING);
90 checkGLcall("glDisable GL_LIGHTING");
94 static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
96 enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE];
97 static UINT once;
99 /* No z test without depth stencil buffers */
100 if (!state->fb->depth_stencil)
102 TRACE("No Z buffer - disabling depth test\n");
103 zenable = WINED3D_ZB_FALSE;
106 switch (zenable)
108 case WINED3D_ZB_FALSE:
109 glDisable(GL_DEPTH_TEST);
110 checkGLcall("glDisable GL_DEPTH_TEST");
111 break;
112 case WINED3D_ZB_TRUE:
113 glEnable(GL_DEPTH_TEST);
114 checkGLcall("glEnable GL_DEPTH_TEST");
115 break;
116 case WINED3D_ZB_USEW:
117 glEnable(GL_DEPTH_TEST);
118 checkGLcall("glEnable GL_DEPTH_TEST");
119 FIXME("W buffer is not well handled\n");
120 break;
121 default:
122 FIXME("Unrecognized depth buffer type %#x.\n", zenable);
123 break;
126 if (context->gl_info->supported[ARB_DEPTH_CLAMP])
128 if (!zenable && context->swapchain->device->strided_streams.position_transformed)
130 glEnable(GL_DEPTH_CLAMP);
131 checkGLcall("glEnable(GL_DEPTH_CLAMP)");
133 else
135 glDisable(GL_DEPTH_CLAMP);
136 checkGLcall("glDisable(GL_DEPTH_CLAMP)");
139 else if (!zenable && !once++)
140 FIXME("Z buffer disabled, but ARB_depth_clamp isn't supported.\n");
143 static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
145 /* glFrontFace() is set in context.c at context init and on an
146 * offscreen / onscreen rendering switch. */
147 switch (state->render_states[WINED3D_RS_CULLMODE])
149 case WINED3D_CULL_NONE:
150 glDisable(GL_CULL_FACE);
151 checkGLcall("glDisable GL_CULL_FACE");
152 break;
153 case WINED3D_CULL_CW:
154 glEnable(GL_CULL_FACE);
155 checkGLcall("glEnable GL_CULL_FACE");
156 glCullFace(GL_FRONT);
157 checkGLcall("glCullFace(GL_FRONT)");
158 break;
159 case WINED3D_CULL_CCW:
160 glEnable(GL_CULL_FACE);
161 checkGLcall("glEnable GL_CULL_FACE");
162 glCullFace(GL_BACK);
163 checkGLcall("glCullFace(GL_BACK)");
164 break;
165 default:
166 FIXME("Unrecognized cull mode %#x.\n",
167 state->render_states[WINED3D_RS_CULLMODE]);
171 static void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
173 switch (state->render_states[WINED3D_RS_SHADEMODE])
175 case WINED3D_SHADE_FLAT:
176 glShadeModel(GL_FLAT);
177 checkGLcall("glShadeModel(GL_FLAT)");
178 break;
179 case WINED3D_SHADE_GOURAUD:
180 glShadeModel(GL_SMOOTH);
181 checkGLcall("glShadeModel(GL_SMOOTH)");
182 break;
183 case WINED3D_SHADE_PHONG:
184 FIXME("WINED3D_SHADE_PHONG isn't supported.\n");
185 break;
186 default:
187 FIXME("Unrecognized shade mode %#x.\n",
188 state->render_states[WINED3D_RS_SHADEMODE]);
192 static void state_ditherenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
194 if (state->render_states[WINED3D_RS_DITHERENABLE])
196 glEnable(GL_DITHER);
197 checkGLcall("glEnable GL_DITHER");
199 else
201 glDisable(GL_DITHER);
202 checkGLcall("glDisable GL_DITHER");
206 static void state_zwritenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
208 /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off.
209 * If yes, this has to be merged with ZENABLE and ZFUNC. */
210 if (state->render_states[WINED3D_RS_ZWRITEENABLE])
212 glDepthMask(1);
213 checkGLcall("glDepthMask(1)");
215 else
217 glDepthMask(0);
218 checkGLcall("glDepthMask(0)");
222 static GLenum gl_compare_func(enum wined3d_cmp_func f)
224 switch (f)
226 case WINED3D_CMP_NEVER:
227 return GL_NEVER;
228 case WINED3D_CMP_LESS:
229 return GL_LESS;
230 case WINED3D_CMP_EQUAL:
231 return GL_EQUAL;
232 case WINED3D_CMP_LESSEQUAL:
233 return GL_LEQUAL;
234 case WINED3D_CMP_GREATER:
235 return GL_GREATER;
236 case WINED3D_CMP_NOTEQUAL:
237 return GL_NOTEQUAL;
238 case WINED3D_CMP_GREATEREQUAL:
239 return GL_GEQUAL;
240 case WINED3D_CMP_ALWAYS:
241 return GL_ALWAYS;
242 default:
243 FIXME("Unrecognized compare function %#x.\n", f);
244 return GL_NONE;
248 static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
250 GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
252 if (!depth_func) return;
254 if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL)
256 static BOOL once;
257 /* There are a few issues with this: First, our inability to
258 * select a proper Z depth, most of the time we're stuck with
259 * D24S8, even if the app selects D32 or D16. There seem to be
260 * some other precision problems which have to be debugged to
261 * make NOTEQUAL and EQUAL work properly. */
262 if (!once)
264 once = TRUE;
265 FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet.\n");
269 glDepthFunc(depth_func);
270 checkGLcall("glDepthFunc");
273 static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
275 float col[4];
277 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col);
278 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
279 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
280 checkGLcall("glLightModel for MODEL_AMBIENT");
283 static void state_blendop_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
285 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
288 static GLenum gl_blend_op(enum wined3d_blend_op op)
290 switch (op)
292 case WINED3D_BLEND_OP_ADD:
293 return GL_FUNC_ADD_EXT;
294 case WINED3D_BLEND_OP_SUBTRACT:
295 return GL_FUNC_SUBTRACT_EXT;
296 case WINED3D_BLEND_OP_REVSUBTRACT:
297 return GL_FUNC_REVERSE_SUBTRACT_EXT;
298 case WINED3D_BLEND_OP_MIN:
299 return GL_MIN_EXT;
300 case WINED3D_BLEND_OP_MAX:
301 return GL_MAX_EXT;
302 default:
303 FIXME("Unhandled blend op %#x.\n", op);
304 return GL_NONE;
308 static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
310 const struct wined3d_gl_info *gl_info = context->gl_info;
311 GLenum blend_equation_alpha = GL_FUNC_ADD_EXT;
312 GLenum blend_equation = GL_FUNC_ADD_EXT;
314 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
315 if (state->render_states[WINED3D_RS_BLENDOPALPHA]
316 && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
318 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
319 return;
322 blend_equation = gl_blend_op(state->render_states[WINED3D_RS_BLENDOP]);
323 blend_equation_alpha = gl_blend_op(state->render_states[WINED3D_RS_BLENDOPALPHA]);
324 TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
326 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
328 GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
329 checkGLcall("glBlendEquationSeparateEXT");
331 else
333 GL_EXTCALL(glBlendEquationEXT(blend_equation));
334 checkGLcall("glBlendEquation");
338 static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_format *dst_format)
340 switch (factor)
342 case WINED3D_BLEND_ZERO:
343 return GL_ZERO;
344 case WINED3D_BLEND_ONE:
345 return GL_ONE;
346 case WINED3D_BLEND_SRCCOLOR:
347 return GL_SRC_COLOR;
348 case WINED3D_BLEND_INVSRCCOLOR:
349 return GL_ONE_MINUS_SRC_COLOR;
350 case WINED3D_BLEND_SRCALPHA:
351 return GL_SRC_ALPHA;
352 case WINED3D_BLEND_INVSRCALPHA:
353 return GL_ONE_MINUS_SRC_ALPHA;
354 case WINED3D_BLEND_DESTCOLOR:
355 return GL_DST_COLOR;
356 case WINED3D_BLEND_INVDESTCOLOR:
357 return GL_ONE_MINUS_DST_COLOR;
358 /* To compensate for the lack of format switching with backbuffer
359 * offscreen rendering, and with onscreen rendering, we modify the
360 * alpha test parameters for (INV)DESTALPHA if the render target
361 * doesn't support alpha blending. A nonexistent alpha channel
362 * returns 1.0, so WINED3D_BLEND_DESTALPHA becomes GL_ONE, and
363 * WINED3D_BLEND_INVDESTALPHA becomes GL_ZERO. */
364 case WINED3D_BLEND_DESTALPHA:
365 return dst_format->alpha_mask ? GL_DST_ALPHA : GL_ONE;
366 case WINED3D_BLEND_INVDESTALPHA:
367 return dst_format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
368 case WINED3D_BLEND_SRCALPHASAT:
369 return GL_SRC_ALPHA_SATURATE;
370 case WINED3D_BLEND_BLENDFACTOR:
371 return GL_CONSTANT_COLOR_EXT;
372 case WINED3D_BLEND_INVBLENDFACTOR:
373 return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
374 default:
375 FIXME("Unhandled blend factor %#x.\n", factor);
376 return GL_NONE;
380 static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
382 const struct wined3d_surface *target = state->fb->render_targets[0];
383 const struct wined3d_gl_info *gl_info = context->gl_info;
384 GLenum srcBlend, dstBlend;
385 enum wined3d_blend d3d_blend;
387 /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
388 * blending parameters to work. */
389 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]
390 || state->render_states[WINED3D_RS_EDGEANTIALIAS]
391 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
393 /* Disable blending in all cases even without pixelshaders.
394 * With blending on we could face a big performance penalty.
395 * The d3d9 visual test confirms the behavior. */
396 if (context->render_offscreen
397 && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
399 glDisable(GL_BLEND);
400 checkGLcall("glDisable GL_BLEND");
401 return;
402 } else {
403 glEnable(GL_BLEND);
404 checkGLcall("glEnable GL_BLEND");
406 } else {
407 glDisable(GL_BLEND);
408 checkGLcall("glDisable GL_BLEND");
409 /* Nothing more to do - get out */
410 return;
413 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
414 * source blending values which are still valid up to d3d9. They should
415 * not occur as dest blend values. */
416 d3d_blend = state->render_states[WINED3D_RS_SRCBLEND];
417 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
419 srcBlend = GL_SRC_ALPHA;
420 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
422 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
424 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
425 dstBlend = GL_SRC_ALPHA;
427 else
429 srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
430 dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
431 target->resource.format);
434 if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
435 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
437 glEnable(GL_LINE_SMOOTH);
438 checkGLcall("glEnable(GL_LINE_SMOOTH)");
439 if(srcBlend != GL_SRC_ALPHA) {
440 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param\n");
442 if(dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE) {
443 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param\n");
445 } else {
446 glDisable(GL_LINE_SMOOTH);
447 checkGLcall("glDisable(GL_LINE_SMOOTH)");
450 /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
451 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP)))
452 state_blendop(context, state, STATE_RENDER(WINED3D_RS_BLENDOPALPHA));
454 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
456 GLenum srcBlendAlpha, dstBlendAlpha;
458 /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
459 if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
461 WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
462 return;
465 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
466 * source blending values which are still valid up to d3d9. They should
467 * not occur as dest blend values. */
468 d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA];
469 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
471 srcBlendAlpha = GL_SRC_ALPHA;
472 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
474 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
476 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
477 dstBlendAlpha = GL_SRC_ALPHA;
479 else
481 srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
482 dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
483 target->resource.format);
486 GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
487 checkGLcall("glBlendFuncSeparateEXT");
488 } else {
489 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
490 glBlendFunc(srcBlend, dstBlend);
491 checkGLcall("glBlendFunc");
494 /* Colorkey fixup for stage 0 alphaop depends on
495 * WINED3D_RS_ALPHABLENDENABLE state, so it may need updating. */
496 if (state->render_states[WINED3D_RS_COLORKEYENABLE])
497 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
500 static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
502 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
505 static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
507 const struct wined3d_gl_info *gl_info = context->gl_info;
508 float col[4];
510 TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
512 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
513 GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
514 checkGLcall("glBlendColor");
517 static void state_alpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
519 int glParm = 0;
520 float ref;
521 BOOL enable_ckey = FALSE;
523 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
525 /* Find out if the texture on the first stage has a ckey set
526 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
527 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
528 * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
529 * in case it finds some texture+colorkeyenable combination which needs extra care.
531 if (state->textures[0])
533 struct wined3d_texture *texture = state->textures[0];
534 GLenum texture_dimensions = texture->target;
536 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
538 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
540 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
542 /* The surface conversion does not do color keying conversion for surfaces that have an alpha
543 * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
544 * surface has alpha bits */
545 if (!surf->resource.format->alpha_mask) enable_ckey = TRUE;
550 if (enable_ckey || context->last_was_ckey)
551 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
552 context->last_was_ckey = enable_ckey;
554 if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
555 || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
557 glEnable(GL_ALPHA_TEST);
558 checkGLcall("glEnable GL_ALPHA_TEST");
559 } else {
560 glDisable(GL_ALPHA_TEST);
561 checkGLcall("glDisable GL_ALPHA_TEST");
562 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
563 * enable call
565 return;
568 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
570 glParm = GL_NOTEQUAL;
571 ref = 0.0f;
573 else
575 ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
576 glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
578 if(glParm) {
579 glAlphaFunc(glParm, ref);
580 checkGLcall("glAlphaFunc");
584 static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
586 const struct wined3d_device *device = context->swapchain->device;
588 /* Vertex and pixel shader states will call a shader upload, don't do
589 * anything as long one of them has an update pending. */
590 if (isStateDirty(context, STATE_VDECL)
591 || isStateDirty(context, STATE_PIXELSHADER))
592 return;
594 device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
597 static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
599 DWORD enable = 0xFFFFFFFF;
600 DWORD disable = 0x00000000;
602 if (use_vs(state))
604 const struct wined3d_device *device = context->swapchain->device;
606 if (!device->vs_clipping)
608 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
609 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
610 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
611 * of that - don't do anything here and keep them disabled
613 if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
615 static BOOL warned = FALSE;
616 if(!warned) {
617 FIXME("Clipping not supported with vertex shaders\n");
618 warned = TRUE;
621 return;
624 /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
625 * hardcoded into the shader. Update the shader to update the enabled clipplanes */
626 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
628 device->shader_backend->shader_select(context, use_ps(state), TRUE);
629 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
630 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
634 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
635 * of already set values
638 /* If enabling / disabling all
639 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
641 if (state->render_states[WINED3D_RS_CLIPPING])
643 enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
644 disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
646 else
648 disable = 0xffffffff;
649 enable = 0x00;
652 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
653 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
654 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
655 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
656 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
657 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
659 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
660 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
661 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
662 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
663 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
664 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
667 static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
669 const struct wined3d_gl_info *gl_info = context->gl_info;
670 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
671 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
672 * specular color. This is wrong:
673 * Separate specular color means the specular colour is maintained separately, whereas
674 * single color means it is merged in. However in both cases they are being used to
675 * some extent.
676 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
677 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
678 * running 1.4 yet!
681 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
682 * Instead, we need to setup the FinalCombiner properly.
684 * The default setup for the FinalCombiner is:
686 * <variable> <input> <mapping> <usage>
687 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
688 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
689 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
690 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
691 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
692 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
693 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
695 * That's pretty much fine as it is, except for variable B, which needs to take
696 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
697 * whether WINED3D_RS_SPECULARENABLE is enabled or not.
700 TRACE("Setting specular enable state and materials\n");
701 if (state->render_states[WINED3D_RS_SPECULARENABLE])
703 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
704 checkGLcall("glMaterialfv");
706 if (state->material.power > gl_info->limits.shininess)
708 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
709 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
710 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
711 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
712 * them, it should be safe to do so without major visual distortions.
714 WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
715 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
717 else
719 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
721 checkGLcall("glMaterialf(GL_SHININESS)");
723 if (gl_info->supported[EXT_SECONDARY_COLOR])
725 glEnable(GL_COLOR_SUM_EXT);
727 else
729 TRACE("Specular colors cannot be enabled in this version of opengl\n");
731 checkGLcall("glEnable(GL_COLOR_SUM)");
733 if (gl_info->supported[NV_REGISTER_COMBINERS])
735 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
736 checkGLcall("glFinalCombinerInputNV()");
738 } else {
739 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
741 /* for the case of enabled lighting: */
742 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
743 checkGLcall("glMaterialfv");
745 /* for the case of disabled lighting: */
746 if (gl_info->supported[EXT_SECONDARY_COLOR])
748 glDisable(GL_COLOR_SUM_EXT);
750 else
752 TRACE("Specular colors cannot be disabled in this version of opengl\n");
754 checkGLcall("glDisable(GL_COLOR_SUM)");
756 if (gl_info->supported[NV_REGISTER_COMBINERS])
758 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
759 checkGLcall("glFinalCombinerInputNV()");
763 TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
764 state->material.diffuse.r, state->material.diffuse.g,
765 state->material.diffuse.b, state->material.diffuse.a);
766 TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
767 state->material.ambient.r, state->material.ambient.g,
768 state->material.ambient.b, state->material.ambient.a);
769 TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
770 state->material.specular.r, state->material.specular.g,
771 state->material.specular.b, state->material.specular.a);
772 TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
773 state->material.emissive.r, state->material.emissive.g,
774 state->material.emissive.b, state->material.emissive.a);
776 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
777 checkGLcall("glMaterialfv(GL_AMBIENT)");
778 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
779 checkGLcall("glMaterialfv(GL_DIFFUSE)");
780 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
781 checkGLcall("glMaterialfv(GL_EMISSION)");
784 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
786 const struct wined3d_gl_info *gl_info = context->gl_info;
787 unsigned int i;
789 /* Note the texture color applies to all textures whereas
790 * GL_TEXTURE_ENV_COLOR applies to active only. */
791 float col[4];
792 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
794 /* And now the default texture color as well */
795 for (i = 0; i < gl_info->limits.texture_stages; ++i)
797 /* Note the WINED3D_RS value applies to all textures, but GL has one
798 * per texture, so apply it now ready to be used! */
799 context_active_texture(context, gl_info, i);
801 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
802 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
806 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
807 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
809 const struct wined3d_gl_info *gl_info = context->gl_info;
811 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
812 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
813 GL_EXTCALL(glActiveStencilFaceEXT(face));
814 checkGLcall("glActiveStencilFaceEXT(...)");
815 glStencilFunc(func, ref, mask);
816 checkGLcall("glStencilFunc(...)");
817 glStencilOp(stencilFail, depthFail, stencilPass);
818 checkGLcall("glStencilOp(...)");
821 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
823 switch (op)
825 case WINED3D_STENCIL_OP_KEEP:
826 return GL_KEEP;
827 case WINED3D_STENCIL_OP_ZERO:
828 return GL_ZERO;
829 case WINED3D_STENCIL_OP_REPLACE:
830 return GL_REPLACE;
831 case WINED3D_STENCIL_OP_INCR_SAT:
832 return GL_INCR;
833 case WINED3D_STENCIL_OP_DECR_SAT:
834 return GL_DECR;
835 case WINED3D_STENCIL_OP_INVERT:
836 return GL_INVERT;
837 case WINED3D_STENCIL_OP_INCR:
838 return GL_INCR_WRAP_EXT;
839 case WINED3D_STENCIL_OP_DECR:
840 return GL_DECR_WRAP_EXT;
841 default:
842 FIXME("Unrecognized stencil op %#x.\n", op);
843 return GL_KEEP;
847 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
849 const struct wined3d_gl_info *gl_info = context->gl_info;
850 DWORD onesided_enable = FALSE;
851 DWORD twosided_enable = FALSE;
852 GLint func = GL_ALWAYS;
853 GLint func_ccw = GL_ALWAYS;
854 GLint ref = 0;
855 GLuint mask = 0;
856 GLint stencilFail = GL_KEEP;
857 GLint depthFail = GL_KEEP;
858 GLint stencilPass = GL_KEEP;
859 GLint stencilFail_ccw = GL_KEEP;
860 GLint depthFail_ccw = GL_KEEP;
861 GLint stencilPass_ccw = GL_KEEP;
863 /* No stencil test without a stencil buffer. */
864 if (!state->fb->depth_stencil)
866 glDisable(GL_STENCIL_TEST);
867 checkGLcall("glDisable GL_STENCIL_TEST");
868 return;
871 onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
872 twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
873 if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
874 func = GL_ALWAYS;
875 if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
876 func_ccw = GL_ALWAYS;
877 ref = state->render_states[WINED3D_RS_STENCILREF];
878 mask = state->render_states[WINED3D_RS_STENCILMASK];
879 stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
880 depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
881 stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
882 stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
883 depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
884 stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
886 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
887 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
888 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
889 onesided_enable, twosided_enable, ref, mask,
890 func, stencilFail, depthFail, stencilPass,
891 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
893 if (twosided_enable && onesided_enable) {
894 glEnable(GL_STENCIL_TEST);
895 checkGLcall("glEnable GL_STENCIL_TEST");
897 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
899 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
900 * which has an effect on the code below too. If we apply the front face
901 * afterwards, we are sure that the active stencil face is set to front,
902 * and other stencil functions which do not use two sided stencil do not have
903 * to set it back
905 renderstate_stencil_twosided(context, GL_BACK,
906 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
907 renderstate_stencil_twosided(context, GL_FRONT,
908 func, ref, mask, stencilFail, depthFail, stencilPass);
910 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
912 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
913 checkGLcall("glStencilFuncSeparateATI(...)");
914 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
915 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
916 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
917 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
918 } else {
919 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
922 else if(onesided_enable)
924 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
926 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
927 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
930 /* This code disables the ATI extension as well, since the standard stencil functions are equal
931 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
933 glEnable(GL_STENCIL_TEST);
934 checkGLcall("glEnable GL_STENCIL_TEST");
935 glStencilFunc(func, ref, mask);
936 checkGLcall("glStencilFunc(...)");
937 glStencilOp(stencilFail, depthFail, stencilPass);
938 checkGLcall("glStencilOp(...)");
939 } else {
940 glDisable(GL_STENCIL_TEST);
941 checkGLcall("glDisable GL_STENCIL_TEST");
945 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
947 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
948 const struct wined3d_gl_info *gl_info = context->gl_info;
950 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
951 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
952 glStencilMask(mask);
953 checkGLcall("glStencilMask");
954 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
955 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
956 glStencilMask(mask);
959 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
961 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
963 glStencilMask(mask);
964 checkGLcall("glStencilMask");
967 static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
970 const struct wined3d_gl_info *gl_info = context->gl_info;
971 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
973 if (!state->render_states[WINED3D_RS_FOGENABLE])
974 return;
976 /* Table fog on: Never use fog coords, and use per-fragment fog */
977 if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
979 glHint(GL_FOG_HINT, GL_NICEST);
980 if(context->fog_coord) {
981 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
982 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
983 context->fog_coord = FALSE;
986 /* Range fog is only used with per-vertex fog in d3d */
987 if (gl_info->supported[NV_FOG_DISTANCE])
989 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
990 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
992 return;
995 /* Otherwise use per-vertex fog in any case */
996 glHint(GL_FOG_HINT, GL_FASTEST);
998 if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
1000 /* No fog at all, or transformed vertices: Use fog coord */
1001 if(!context->fog_coord) {
1002 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1003 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
1004 context->fog_coord = TRUE;
1007 else
1009 /* Otherwise, use the fragment depth */
1010 if(context->fog_coord) {
1011 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1012 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1013 context->fog_coord = FALSE;
1016 if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
1018 if (gl_info->supported[NV_FOG_DISTANCE])
1020 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1021 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1023 else
1025 WARN("Range fog enabled, but not supported by this GL implementation.\n");
1028 else if (gl_info->supported[NV_FOG_DISTANCE])
1030 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1031 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1036 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1038 float fogstart, fogend;
1039 union {
1040 DWORD d;
1041 float f;
1042 } tmpvalue;
1044 switch(context->fog_source) {
1045 case FOGSOURCE_VS:
1046 fogstart = 1.0f;
1047 fogend = 0.0f;
1048 break;
1050 case FOGSOURCE_COORD:
1051 fogstart = 255.0f;
1052 fogend = 0.0f;
1053 break;
1055 case FOGSOURCE_FFP:
1056 tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
1057 fogstart = tmpvalue.f;
1058 tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
1059 fogend = tmpvalue.f;
1060 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
1061 if(fogstart == fogend) {
1062 fogstart = -1.0f / 0.0f;
1063 fogend = 0.0f;
1065 break;
1067 default:
1068 /* This should not happen.context->fog_source is set in wined3d, not the app.
1069 * Still this is needed to make the compiler happy
1071 ERR("Unexpected fog coordinate source\n");
1072 fogstart = 0.0f;
1073 fogend = 0.0f;
1076 glFogf(GL_FOG_START, fogstart);
1077 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1078 TRACE("Fog Start == %f\n", fogstart);
1080 glFogf(GL_FOG_END, fogend);
1081 checkGLcall("glFogf(GL_FOG_END, fogend)");
1082 TRACE("Fog End == %f\n", fogend);
1085 void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1087 enum fogsource new_source;
1089 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
1091 if (!state->render_states[WINED3D_RS_FOGENABLE])
1093 /* No fog? Disable it, and we're done :-) */
1094 glDisableWINE(GL_FOG);
1095 checkGLcall("glDisable GL_FOG");
1096 return;
1099 /* Fog Rules:
1101 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1102 * It can use the Z value of the vertex, or the alpha component of the specular color.
1103 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1104 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1105 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1107 * FOGTABLEMODE != NONE:
1108 * The Z value is used, with the equation specified, no matter what vertex type.
1110 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1111 * Per vertex fog is calculated using the specified fog equation and the parameters
1113 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1114 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1115 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1118 * Rules for vertex fog with shaders:
1120 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1121 * the fog computation to happen during transformation while openGL expects it to happen
1122 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1123 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1124 * To solve this problem, WineD3D does:
1125 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1126 * shader,
1127 * and 2) disables the fog computation (in either the fixed function or programmable
1128 * rasterizer) if using a vertex program.
1130 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1131 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1132 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1133 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1134 * There are some GL differences between specular fog coords and vertex shaders though.
1136 * With table fog the vertex shader fog coordinate is ignored.
1138 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1139 * without shaders).
1142 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1143 * the system will apply only pixel(=table) fog effects."
1145 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
1147 if (use_vs(state))
1149 glFogi(GL_FOG_MODE, GL_LINEAR);
1150 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1151 new_source = FOGSOURCE_VS;
1153 else
1155 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
1157 /* If processed vertices are used, fall through to the NONE case */
1158 case WINED3D_FOG_EXP:
1159 if (!context->last_was_rhw)
1161 glFogi(GL_FOG_MODE, GL_EXP);
1162 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1163 new_source = FOGSOURCE_FFP;
1164 break;
1166 /* drop through */
1168 case WINED3D_FOG_EXP2:
1169 if (!context->last_was_rhw)
1171 glFogi(GL_FOG_MODE, GL_EXP2);
1172 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1173 new_source = FOGSOURCE_FFP;
1174 break;
1176 /* drop through */
1178 case WINED3D_FOG_LINEAR:
1179 if (!context->last_was_rhw)
1181 glFogi(GL_FOG_MODE, GL_LINEAR);
1182 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1183 new_source = FOGSOURCE_FFP;
1184 break;
1186 /* drop through */
1188 case WINED3D_FOG_NONE:
1189 /* Both are none? According to msdn the alpha channel of the specular
1190 * color contains a fog factor. Set it in drawStridedSlow.
1191 * Same happens with Vertexfog on transformed vertices
1193 new_source = FOGSOURCE_COORD;
1194 glFogi(GL_FOG_MODE, GL_LINEAR);
1195 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1196 break;
1198 default:
1199 FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
1200 state->render_states[WINED3D_RS_FOGVERTEXMODE]);
1201 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1204 } else {
1205 new_source = FOGSOURCE_FFP;
1207 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
1209 case WINED3D_FOG_EXP:
1210 glFogi(GL_FOG_MODE, GL_EXP);
1211 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1212 break;
1214 case WINED3D_FOG_EXP2:
1215 glFogi(GL_FOG_MODE, GL_EXP2);
1216 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1217 break;
1219 case WINED3D_FOG_LINEAR:
1220 glFogi(GL_FOG_MODE, GL_LINEAR);
1221 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1222 break;
1224 case WINED3D_FOG_NONE: /* Won't happen */
1225 default:
1226 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
1227 state->render_states[WINED3D_RS_FOGTABLEMODE]);
1231 glEnableWINE(GL_FOG);
1232 checkGLcall("glEnable GL_FOG");
1233 if (new_source != context->fog_source)
1235 context->fog_source = new_source;
1236 state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
1240 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1242 float col[4];
1244 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
1245 glFogfv(GL_FOG_COLOR, &col[0]);
1246 checkGLcall("glFog GL_FOG_COLOR");
1249 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1251 union {
1252 DWORD d;
1253 float f;
1254 } tmpvalue;
1256 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1257 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1258 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1261 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1263 const struct wined3d_device *device = context->swapchain->device;
1264 GLenum Parm = 0;
1266 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1267 * The vertex declaration will call this function if the fixed function pipeline is used.
1270 if(isStateDirty(context, STATE_VDECL)) {
1271 return;
1274 context->num_untracked_materials = 0;
1275 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1276 && state->render_states[WINED3D_RS_COLORVERTEX])
1278 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1279 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
1280 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
1281 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
1282 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
1284 if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1286 if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1287 Parm = GL_AMBIENT_AND_DIFFUSE;
1288 else
1289 Parm = GL_DIFFUSE;
1290 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1292 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1293 context->num_untracked_materials++;
1295 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1297 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1298 context->num_untracked_materials++;
1301 else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1303 Parm = GL_AMBIENT;
1304 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1306 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1307 context->num_untracked_materials++;
1309 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1311 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1312 context->num_untracked_materials++;
1315 else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1317 Parm = GL_EMISSION;
1318 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1320 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1321 context->num_untracked_materials++;
1324 else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1326 Parm = GL_SPECULAR;
1330 /* Nothing changed, return. */
1331 if (Parm == context->tracking_parm) return;
1333 if(!Parm) {
1334 glDisable(GL_COLOR_MATERIAL);
1335 checkGLcall("glDisable GL_COLOR_MATERIAL");
1336 } else {
1337 glColorMaterial(GL_FRONT_AND_BACK, Parm);
1338 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1339 glEnable(GL_COLOR_MATERIAL);
1340 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1343 /* Apparently calls to glMaterialfv are ignored for properties we're
1344 * tracking with glColorMaterial, so apply those here. */
1345 switch (context->tracking_parm) {
1346 case GL_AMBIENT_AND_DIFFUSE:
1347 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1348 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1349 checkGLcall("glMaterialfv");
1350 break;
1352 case GL_DIFFUSE:
1353 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1354 checkGLcall("glMaterialfv");
1355 break;
1357 case GL_AMBIENT:
1358 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1359 checkGLcall("glMaterialfv");
1360 break;
1362 case GL_EMISSION:
1363 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
1364 checkGLcall("glMaterialfv");
1365 break;
1367 case GL_SPECULAR:
1368 /* Only change material color if specular is enabled, otherwise it is set to black */
1369 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1371 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
1372 checkGLcall("glMaterialfv");
1374 else
1376 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1377 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1378 checkGLcall("glMaterialfv");
1380 break;
1383 context->tracking_parm = Parm;
1386 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1388 union
1390 DWORD d;
1391 struct wined3d_line_pattern lp;
1392 } tmppattern;
1393 tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
1395 TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1397 if (tmppattern.lp.repeat_factor)
1399 glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1400 checkGLcall("glLineStipple(repeat, linepattern)");
1401 glEnable(GL_LINE_STIPPLE);
1402 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1404 else
1406 glDisable(GL_LINE_STIPPLE);
1407 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1411 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1413 if (isStateDirty(context, STATE_VDECL))
1414 return;
1416 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1417 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1418 * by zero and is not properly defined in opengl, so avoid it
1420 if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
1421 && (context->swapchain->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1423 glEnable(GL_NORMALIZE);
1424 checkGLcall("glEnable(GL_NORMALIZE);");
1426 else
1428 glDisable(GL_NORMALIZE);
1429 checkGLcall("glDisable(GL_NORMALIZE);");
1433 static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1435 union {
1436 DWORD d;
1437 float f;
1438 } tmpvalue;
1440 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1441 if (tmpvalue.f != 1.0f)
1443 FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1445 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1446 if (tmpvalue.f != 64.0f)
1448 FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1453 static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1455 const struct wined3d_gl_info *gl_info = context->gl_info;
1456 union
1458 DWORD d;
1459 float f;
1460 } min, max;
1462 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1463 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1465 /* Max point size trumps min point size */
1466 if(min.f > max.f) {
1467 min.f = max.f;
1470 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1471 checkGLcall("glPointParameterfEXT(...)");
1472 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1473 checkGLcall("glPointParameterfEXT(...)");
1476 static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1478 const struct wined3d_gl_info *gl_info = context->gl_info;
1479 union
1481 DWORD d;
1482 float f;
1483 } min, max;
1485 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1486 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1488 /* Max point size trumps min point size */
1489 if(min.f > max.f) {
1490 min.f = max.f;
1493 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1494 checkGLcall("glPointParameterfARB(...)");
1495 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1496 checkGLcall("glPointParameterfARB(...)");
1499 static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1501 const struct wined3d_gl_info *gl_info = context->gl_info;
1502 /* TODO: Group this with the viewport */
1504 * POINTSCALEENABLE controls how point size value is treated. If set to
1505 * true, the point size is scaled with respect to height of viewport.
1506 * When set to false point size is in pixels.
1509 /* Default values */
1510 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1511 union {
1512 DWORD d;
1513 float f;
1514 } pointSize, A, B, C;
1516 pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
1517 A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
1518 B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
1519 C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
1521 if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1523 DWORD h = state->viewport.height;
1524 GLfloat scaleFactor;
1526 if (pointSize.f < gl_info->limits.pointsize_min)
1528 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1529 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1530 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1531 * are less than 1.0f. scale_factor = 1.0f / point_size.
1533 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1534 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1535 * is 1.0, but then accepts points below that and draws too small points
1537 pointSize.f = gl_info->limits.pointsize_min;
1539 else if(pointSize.f > gl_info->limits.pointsize_max)
1541 /* gl already scales the input to glPointSize,
1542 * d3d scales the result after the point size scale.
1543 * If the point size is bigger than the max size, use the
1544 * scaling to scale it bigger, and set the gl point size to max
1546 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1547 TRACE("scale: %f\n", scaleFactor);
1548 pointSize.f = gl_info->limits.pointsize_max;
1549 } else {
1550 scaleFactor = 1.0f;
1552 scaleFactor = powf(h * scaleFactor, 2);
1554 att[0] = A.f / scaleFactor;
1555 att[1] = B.f / scaleFactor;
1556 att[2] = C.f / scaleFactor;
1559 if (gl_info->supported[ARB_POINT_PARAMETERS])
1561 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1562 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1564 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1566 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1567 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1569 else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1571 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1574 glPointSize(pointSize.f);
1575 checkGLcall("glPointSize(...);");
1578 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1580 WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
1583 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1585 DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
1586 DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
1587 DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
1588 DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
1590 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1591 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1592 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1593 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1594 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1595 glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1596 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1597 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1598 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1599 checkGLcall("glColorMask(...)");
1601 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1602 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1604 FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1605 mask0, mask1, mask2, mask3);
1606 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1610 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1612 GL_EXTCALL(glColorMaskIndexedEXT(index,
1613 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1614 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1615 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1616 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1619 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1621 set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
1624 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1626 set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
1629 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1631 set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
1634 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1636 set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
1639 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1641 if (state->render_states[WINED3D_RS_LOCALVIEWER])
1643 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1644 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1645 } else {
1646 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1647 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1651 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1653 if (state->render_states[WINED3D_RS_LASTPIXEL])
1655 TRACE("Last Pixel Drawing Enabled\n");
1657 else
1659 static BOOL warned;
1660 if (!warned) {
1661 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1662 warned = TRUE;
1663 } else {
1664 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1669 static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1671 static BOOL warned;
1673 /* TODO: NV_POINT_SPRITE */
1674 if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1676 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1677 FIXME("Point sprites not supported\n");
1678 warned = TRUE;
1682 static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1684 if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1686 glEnable(GL_POINT_SPRITE_ARB);
1687 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1688 } else {
1689 glDisable(GL_POINT_SPRITE_ARB);
1690 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1694 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1696 if (state->render_states[WINED3D_RS_WRAP0]
1697 || state->render_states[WINED3D_RS_WRAP1]
1698 || state->render_states[WINED3D_RS_WRAP2]
1699 || state->render_states[WINED3D_RS_WRAP3]
1700 || state->render_states[WINED3D_RS_WRAP4]
1701 || state->render_states[WINED3D_RS_WRAP5]
1702 || state->render_states[WINED3D_RS_WRAP6]
1703 || state->render_states[WINED3D_RS_WRAP7]
1704 || state->render_states[WINED3D_RS_WRAP8]
1705 || state->render_states[WINED3D_RS_WRAP9]
1706 || state->render_states[WINED3D_RS_WRAP10]
1707 || state->render_states[WINED3D_RS_WRAP11]
1708 || state->render_states[WINED3D_RS_WRAP12]
1709 || state->render_states[WINED3D_RS_WRAP13]
1710 || state->render_states[WINED3D_RS_WRAP14]
1711 || state->render_states[WINED3D_RS_WRAP15])
1712 FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
1715 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1717 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1718 WARN("Multisample antialiasing not supported by GL.\n");
1721 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1723 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1725 glEnable(GL_MULTISAMPLE_ARB);
1726 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1727 } else {
1728 glDisable(GL_MULTISAMPLE_ARB);
1729 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1733 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1735 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
1737 glEnable(GL_SCISSOR_TEST);
1738 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1739 } else {
1740 glDisable(GL_SCISSOR_TEST);
1741 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1745 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1746 * OpenGL the bias is specified in units of "the smallest value that is
1747 * guaranteed to produce a resolvable offset for a given implementation". To
1748 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1749 * There's no practical way to retrieve that value from a given GL
1750 * implementation, but the D3D application has essentially the same problem,
1751 * which makes a guess of the depth buffer format's highest possible value a
1752 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1753 * depth slope, and doesn't need to be scaled. */
1754 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1756 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
1757 || state->render_states[WINED3D_RS_DEPTHBIAS])
1759 const struct wined3d_surface *depth = state->fb->depth_stencil;
1760 float scale;
1762 union
1764 DWORD d;
1765 float f;
1766 } scale_bias, const_bias;
1768 scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
1769 const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
1771 glEnable(GL_POLYGON_OFFSET_FILL);
1772 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1774 if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
1776 float bias = -(float)const_bias.d;
1777 glPolygonOffset(bias, bias);
1778 checkGLcall("glPolygonOffset");
1780 else
1782 if (depth)
1784 const struct wined3d_format *fmt = depth->resource.format;
1785 scale = powf(2, fmt->depth_size) - 1;
1786 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
1787 debug_d3dformat(fmt->id), scale);
1789 else
1791 /* The context manager will reapply this state on a depth stencil change */
1792 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
1793 scale = 0.0f;
1796 glPolygonOffset(scale_bias.f, const_bias.f * scale);
1797 checkGLcall("glPolygonOffset(...)");
1800 else
1802 glDisable(GL_POLYGON_OFFSET_FILL);
1803 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1807 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1809 if (state->render_states[WINED3D_RS_ZVISIBLE])
1810 FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
1813 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1815 if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
1817 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1818 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1819 } else {
1820 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1821 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1825 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1827 if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
1828 FIXME("Stippled Alpha not supported yet.\n");
1831 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1833 if (state->render_states[WINED3D_RS_ANTIALIAS])
1834 FIXME("Antialias not supported yet.\n");
1837 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1839 if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
1840 FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
1841 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
1844 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1846 if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
1847 FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
1848 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
1851 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1853 union {
1854 DWORD d;
1855 float f;
1856 } tmpvalue;
1857 tmpvalue.f = 1.0f;
1859 if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
1861 static BOOL displayed = FALSE;
1863 tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
1864 if(!displayed)
1865 FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1867 displayed = TRUE;
1871 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1873 if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
1874 FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
1875 state->render_states[WINED3D_RS_POSITIONDEGREE]);
1878 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1880 if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
1881 FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
1882 state->render_states[WINED3D_RS_NORMALDEGREE]);
1885 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1887 if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
1888 FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1889 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
1892 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1894 union {
1895 DWORD d;
1896 float f;
1897 } zmin, zmax;
1899 const struct wined3d_gl_info *gl_info = context->gl_info;
1901 if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1903 zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
1904 zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
1906 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1907 * In d3d9 test is not performed in this case*/
1908 if (zmin.f <= zmax.f)
1910 glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1911 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1912 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1913 checkGLcall("glDepthBoundsEXT(...)");
1915 else {
1916 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1917 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1920 else {
1921 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1922 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1925 state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
1928 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1930 if (state->render_states[WINED3D_RS_WRAPU])
1931 FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
1934 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1936 if (state->render_states[WINED3D_RS_WRAPV])
1937 FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
1940 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1942 if (state->render_states[WINED3D_RS_MONOENABLE])
1943 FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
1946 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1948 if (state->render_states[WINED3D_RS_ROP2])
1949 FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
1952 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1954 if (state->render_states[WINED3D_RS_PLANEMASK])
1955 FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
1958 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1960 if (state->render_states[WINED3D_RS_SUBPIXEL])
1961 FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
1964 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1966 if (state->render_states[WINED3D_RS_SUBPIXELX])
1967 FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
1970 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1972 if (state->render_states[WINED3D_RS_STIPPLEENABLE])
1973 FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
1976 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1978 if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
1979 FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
1982 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1984 if (state->render_states[WINED3D_RS_ANISOTROPY])
1985 FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
1988 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1990 if (state->render_states[WINED3D_RS_FLUSHBATCH])
1991 FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
1994 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1996 if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
1997 FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
2000 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2002 if (state->render_states[WINED3D_RS_EXTENTS])
2003 FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
2006 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2008 if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
2009 FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
2012 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2014 if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
2015 FIXME("Software vertex processing not implemented.\n");
2018 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2019 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2020 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2021 * flag specifies the complement of the input should be used. */
2022 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2023 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2025 /* Calculate the operand */
2026 if (complement) {
2027 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2028 else *operand = GL_ONE_MINUS_SRC_COLOR;
2029 } else {
2030 if (from_alpha) *operand = GL_SRC_ALPHA;
2031 else *operand = GL_SRC_COLOR;
2034 /* Calculate the source */
2035 switch (arg & WINED3DTA_SELECTMASK) {
2036 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2037 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2038 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2039 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2040 case WINED3DTA_SPECULAR:
2042 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2043 * 'Secondary color' and isn't supported until base GL supports it
2044 * There is no concept of temp registers as far as I can tell
2046 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2047 *source = GL_TEXTURE;
2048 break;
2049 default:
2050 FIXME("Unrecognized texture arg %#x\n", arg);
2051 *source = GL_TEXTURE;
2052 break;
2056 /* Setup the texture operations texture stage states */
2057 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2058 BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2060 GLenum src1, src2, src3;
2061 GLenum opr1, opr2, opr3;
2062 GLenum comb_target;
2063 GLenum src0_target, src1_target, src2_target;
2064 GLenum opr0_target, opr1_target, opr2_target;
2065 GLenum scal_target;
2066 GLenum opr=0, invopr, src3_target, opr3_target;
2067 BOOL Handled = FALSE;
2069 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2071 /* This is called by a state handler which has the gl lock held and a context for the thread */
2073 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2074 the form (a1 <operation> a2). However, some of the more complex operations
2075 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2076 in a third parameter called a0. Therefore these are operations of the form
2077 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2079 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2080 functions below, expect their syntax to differ slightly to those listed in the
2081 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2082 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2084 if (isAlpha)
2086 comb_target = GL_COMBINE_ALPHA;
2087 src0_target = GL_SOURCE0_ALPHA;
2088 src1_target = GL_SOURCE1_ALPHA;
2089 src2_target = GL_SOURCE2_ALPHA;
2090 opr0_target = GL_OPERAND0_ALPHA;
2091 opr1_target = GL_OPERAND1_ALPHA;
2092 opr2_target = GL_OPERAND2_ALPHA;
2093 scal_target = GL_ALPHA_SCALE;
2095 else
2097 comb_target = GL_COMBINE_RGB;
2098 src0_target = GL_SOURCE0_RGB;
2099 src1_target = GL_SOURCE1_RGB;
2100 src2_target = GL_SOURCE2_RGB;
2101 opr0_target = GL_OPERAND0_RGB;
2102 opr1_target = GL_OPERAND1_RGB;
2103 opr2_target = GL_OPERAND2_RGB;
2104 scal_target = GL_RGB_SCALE;
2107 /* If a texture stage references an invalid texture unit the stage just
2108 * passes through the result from the previous stage */
2109 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2111 arg1 = WINED3DTA_CURRENT;
2112 op = WINED3D_TOP_SELECT_ARG1;
2115 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2117 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2118 } else {
2119 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2121 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2122 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2124 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2126 Handled = TRUE; /* Assume will be handled */
2128 /* Other texture operations require special extensions: */
2129 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2131 if (isAlpha) {
2132 opr = GL_SRC_ALPHA;
2133 invopr = GL_ONE_MINUS_SRC_ALPHA;
2134 src3_target = GL_SOURCE3_ALPHA_NV;
2135 opr3_target = GL_OPERAND3_ALPHA_NV;
2136 } else {
2137 opr = GL_SRC_COLOR;
2138 invopr = GL_ONE_MINUS_SRC_COLOR;
2139 src3_target = GL_SOURCE3_RGB_NV;
2140 opr3_target = GL_OPERAND3_RGB_NV;
2142 switch (op)
2144 case WINED3D_TOP_DISABLE: /* Only for alpha */
2145 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2146 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2147 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2148 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2149 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2150 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2151 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2152 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2153 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2154 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2155 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2156 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2157 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2158 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2159 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2160 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2161 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2162 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2163 break;
2164 case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
2165 case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
2166 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2167 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2168 if (op == WINED3D_TOP_SELECT_ARG1)
2170 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2171 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2172 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2173 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2174 } else {
2175 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2176 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2177 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2178 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2180 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2181 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2182 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2183 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2184 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2185 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2186 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2187 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2188 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2189 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2190 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2191 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2192 break;
2194 case WINED3D_TOP_MODULATE:
2195 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2196 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2197 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2198 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2199 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2200 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2201 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2202 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2203 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2204 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2205 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2206 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2207 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2208 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2209 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2210 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2211 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2212 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2213 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2214 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2215 break;
2216 case WINED3D_TOP_MODULATE_2X:
2217 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2218 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2219 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2220 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2221 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2222 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2223 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2224 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2225 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2226 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2227 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2228 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2229 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2230 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2231 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2232 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2233 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2234 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2235 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2236 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2237 break;
2238 case WINED3D_TOP_MODULATE_4X:
2239 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2240 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2241 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2242 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2243 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2244 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2245 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2246 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2247 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2248 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2249 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2250 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2251 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2252 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2253 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2254 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2255 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2256 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2257 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2258 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2259 break;
2261 case WINED3D_TOP_ADD:
2262 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2263 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2264 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2265 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2266 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2267 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2268 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2269 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2270 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2271 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2272 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2273 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2274 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2275 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2276 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2277 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2278 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2279 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2280 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2281 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2282 break;
2284 case WINED3D_TOP_ADD_SIGNED:
2285 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2286 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2287 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2288 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2289 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2290 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2291 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2292 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2293 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2294 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2295 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2296 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2297 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2298 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2299 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2300 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2301 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2302 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2303 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2304 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2305 break;
2307 case WINED3D_TOP_ADD_SIGNED_2X:
2308 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2309 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2310 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2311 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2312 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2313 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2314 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2315 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2316 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2317 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2318 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2319 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2320 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2321 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2322 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2323 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2324 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2325 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2326 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2327 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2328 break;
2330 case WINED3D_TOP_ADD_SMOOTH:
2331 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2332 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2333 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2334 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2335 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2336 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2337 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2338 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2339 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2340 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2341 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2342 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2343 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2344 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2345 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2346 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2347 switch (opr1) {
2348 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2349 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2350 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2351 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2353 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2354 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2355 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2356 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2357 break;
2359 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2360 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2361 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2362 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2363 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2364 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2365 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2366 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
2367 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
2368 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2369 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2370 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2371 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2372 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2373 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2374 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
2375 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
2376 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2377 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2378 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2379 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2380 break;
2381 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2382 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2383 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2384 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2385 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2386 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2387 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2388 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2389 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2390 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2391 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2392 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2393 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2394 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2395 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2396 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2397 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2398 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2399 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2400 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2401 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2402 break;
2403 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2404 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2405 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2406 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2407 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2408 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2409 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2410 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
2411 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
2412 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2413 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2414 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2415 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2416 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2417 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2418 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
2419 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
2420 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2421 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2422 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2423 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2424 break;
2425 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2426 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2427 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2428 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2429 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2430 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2431 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2432 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2433 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2434 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2435 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2436 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2437 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2438 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2439 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2440 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2441 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2442 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2443 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2444 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2445 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2446 break;
2447 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2448 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2449 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2450 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2451 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2452 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2453 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2454 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2455 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2456 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2457 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2458 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2459 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2460 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2461 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2462 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2463 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2464 switch (opr) {
2465 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2466 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2468 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2469 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2470 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2471 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2472 break;
2473 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2474 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2475 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2476 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2477 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2478 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2479 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2480 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2481 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2482 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2483 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2484 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2485 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2486 switch (opr1) {
2487 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2488 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2490 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2491 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2492 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2493 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2494 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2495 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2496 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2497 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2498 break;
2499 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2500 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2501 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2502 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2503 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2504 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2505 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2506 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2507 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2508 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2509 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2510 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2511 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2512 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2513 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2514 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2515 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2516 switch (opr1) {
2517 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2518 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2519 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2520 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2522 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2523 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2524 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2525 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2526 break;
2527 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2528 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2529 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2530 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2531 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2532 switch (opr1) {
2533 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2534 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2535 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2536 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2538 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2539 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2540 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2541 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2542 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2543 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2544 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2545 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2546 switch (opr1) {
2547 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2548 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2550 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2551 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2552 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2553 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2554 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2555 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2556 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2557 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2558 break;
2559 case WINED3D_TOP_MULTIPLY_ADD:
2560 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2561 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2562 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2563 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2564 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2565 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2566 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2567 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2568 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2569 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2570 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2571 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2572 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2573 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2574 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2575 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2576 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2577 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2578 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2579 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2580 break;
2582 case WINED3D_TOP_BUMPENVMAP:
2583 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
2584 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2586 default:
2587 Handled = FALSE;
2589 if (Handled) {
2590 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2591 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2593 return;
2595 } /* GL_NV_texture_env_combine4 */
2597 Handled = TRUE; /* Again, assume handled */
2598 switch (op) {
2599 case WINED3D_TOP_DISABLE: /* Only for alpha */
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, GL_PREVIOUS_EXT);
2603 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2604 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2605 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2606 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2607 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2608 break;
2609 case WINED3D_TOP_SELECT_ARG1:
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, src1);
2613 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2614 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2615 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2616 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2617 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2618 break;
2619 case WINED3D_TOP_SELECT_ARG2:
2620 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2621 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2622 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2623 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2624 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2625 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2626 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2627 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2628 break;
2629 case WINED3D_TOP_MODULATE:
2630 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2631 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2632 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2633 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2634 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2635 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2636 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2637 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2638 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2639 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2640 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2641 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2642 break;
2643 case WINED3D_TOP_MODULATE_2X:
2644 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2645 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2646 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2647 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2648 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2649 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2650 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2651 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2652 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2653 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2654 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2655 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2656 break;
2657 case WINED3D_TOP_MODULATE_4X:
2658 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2659 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2660 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2661 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2662 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2663 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2664 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2665 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2666 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2667 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2668 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2669 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2670 break;
2671 case WINED3D_TOP_ADD:
2672 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2673 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2674 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2675 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2676 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2677 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2678 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2679 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2680 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2681 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2682 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2683 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2684 break;
2685 case WINED3D_TOP_ADD_SIGNED:
2686 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2687 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2688 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2689 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2690 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2691 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2692 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2693 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2694 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2695 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2696 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2697 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2698 break;
2699 case WINED3D_TOP_ADD_SIGNED_2X:
2700 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2701 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2702 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2703 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2704 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2705 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2706 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2707 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2708 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2709 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2710 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2711 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2712 break;
2713 case WINED3D_TOP_SUBTRACT:
2714 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2716 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2717 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2718 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2719 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2720 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2721 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2722 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2723 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2724 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2725 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2726 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2727 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2728 } else {
2729 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2731 break;
2733 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2734 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2735 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2736 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2737 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2738 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2739 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2740 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2741 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2742 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2743 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2744 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
2745 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2746 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2747 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2748 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2749 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2750 break;
2751 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2752 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2753 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2754 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2755 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2756 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2757 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2758 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2759 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2760 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2761 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2762 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2763 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2764 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2765 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2766 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2767 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2768 break;
2769 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2770 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2771 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2772 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2773 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2774 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2775 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2776 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2777 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2778 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2779 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2780 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
2781 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2782 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2783 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2784 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2785 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2786 break;
2787 case WINED3D_TOP_BLEND_CURRENT_ALPHA:
2788 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2789 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2790 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2791 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2792 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2793 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2794 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2795 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2796 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2797 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2798 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
2799 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2800 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2801 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2802 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2803 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2804 break;
2805 case WINED3D_TOP_DOTPRODUCT3:
2806 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2808 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2809 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2811 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2813 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2814 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2815 } else {
2816 FIXME("This version of opengl does not support GL_DOT3\n");
2818 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2819 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2820 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2821 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2822 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2823 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2824 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2825 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2826 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2827 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2828 break;
2829 case WINED3D_TOP_LERP:
2830 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2831 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2832 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2833 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2834 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2835 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2836 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2837 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2838 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2839 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2840 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2841 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2842 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2843 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2844 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2845 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2846 break;
2847 case WINED3D_TOP_ADD_SMOOTH:
2848 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2850 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2851 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2852 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2853 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2854 switch (opr1) {
2855 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2856 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2857 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2858 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2860 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2861 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2862 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2863 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2864 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2865 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2866 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2867 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2868 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2869 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2870 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2871 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2872 } else
2873 Handled = FALSE;
2874 break;
2875 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2876 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2878 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2879 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2880 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2881 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2882 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2883 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2884 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2885 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2886 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2887 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2888 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2889 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2890 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2891 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2892 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2893 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2894 } else
2895 Handled = FALSE;
2896 break;
2897 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2898 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2900 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2901 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2902 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2903 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2904 switch (opr1) {
2905 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2906 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2907 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2908 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2910 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2911 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2912 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2913 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2914 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2915 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2916 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2917 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2918 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2919 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2920 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2921 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2922 } else
2923 Handled = FALSE;
2924 break;
2925 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2926 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2928 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2929 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2930 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2931 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2932 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2933 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2934 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2935 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2936 switch (opr1) {
2937 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2938 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2939 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2940 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2942 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2943 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2944 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2945 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2946 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2947 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2948 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2949 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2950 } else
2951 Handled = FALSE;
2952 break;
2953 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2954 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2956 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2957 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2958 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2959 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2960 switch (opr1) {
2961 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2962 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2963 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2964 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2966 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2967 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2968 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2969 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2970 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2971 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2972 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2973 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2974 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2975 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2976 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2977 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2978 } else
2979 Handled = FALSE;
2980 break;
2981 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2982 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2984 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2985 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2986 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2987 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2988 switch (opr1) {
2989 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2990 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2991 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2992 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2994 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2995 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2996 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2997 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2998 switch (opr1) {
2999 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3000 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3001 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3002 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3004 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
3005 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
3006 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3007 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3008 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3009 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3010 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3011 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3012 } else
3013 Handled = FALSE;
3014 break;
3015 case WINED3D_TOP_MULTIPLY_ADD:
3016 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3018 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3019 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3020 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3021 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3022 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3023 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3024 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3025 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3026 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3027 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3028 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3029 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3030 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3031 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3032 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3033 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3034 } else
3035 Handled = FALSE;
3036 break;
3037 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3038 case WINED3D_TOP_BUMPENVMAP:
3039 if (gl_info->supported[NV_TEXTURE_SHADER2])
3041 /* Technically texture shader support without register combiners is possible, but not expected to occur
3042 * on real world cards, so for now a fixme should be enough
3044 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3046 default:
3047 Handled = FALSE;
3050 if (Handled) {
3051 BOOL combineOK = TRUE;
3052 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3054 DWORD op2;
3056 if (isAlpha)
3057 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3058 else
3059 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3061 /* Note: If COMBINE4 in effect can't go back to combine! */
3062 switch (op2)
3064 case WINED3D_TOP_ADD_SMOOTH:
3065 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3066 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3067 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3068 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3069 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3070 case WINED3D_TOP_MULTIPLY_ADD:
3071 /* Ignore those implemented in both cases */
3072 switch (op)
3074 case WINED3D_TOP_SELECT_ARG1:
3075 case WINED3D_TOP_SELECT_ARG2:
3076 combineOK = FALSE;
3077 Handled = FALSE;
3078 break;
3079 default:
3080 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3081 return;
3086 if (combineOK)
3088 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3089 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3091 return;
3095 /* After all the extensions, if still unhandled, report fixme */
3096 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3100 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3102 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3103 const struct wined3d_device *device = context->swapchain->device;
3104 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3105 DWORD mapped_stage = device->texUnitMap[stage];
3106 const struct wined3d_gl_info *gl_info = context->gl_info;
3108 TRACE("Setting color op for stage %d\n", stage);
3110 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3111 if (use_ps(state)) return;
3113 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3115 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3117 if (tex_used && mapped_stage >= gl_info->limits.textures)
3119 FIXME("Attempt to enable unsupported stage!\n");
3120 return;
3122 context_active_texture(context, gl_info, mapped_stage);
3125 if (stage >= state->lowest_disabled_stage)
3127 TRACE("Stage disabled\n");
3128 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3130 /* Disable everything here */
3131 glDisable(GL_TEXTURE_2D);
3132 checkGLcall("glDisable(GL_TEXTURE_2D)");
3133 glDisable(GL_TEXTURE_3D);
3134 checkGLcall("glDisable(GL_TEXTURE_3D)");
3135 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3137 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3138 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3140 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3142 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3143 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3146 /* All done */
3147 return;
3150 /* The sampler will also activate the correct texture dimensions, so no
3151 * need to do it here if the sampler for this stage is dirty. */
3152 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3153 texture_activate_dimensions(state->textures[stage], gl_info);
3155 set_tex_op(gl_info, state, FALSE, stage,
3156 state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3157 state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3158 state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3159 state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3162 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3164 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3165 const struct wined3d_device *device = context->swapchain->device;
3166 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3167 DWORD mapped_stage = device->texUnitMap[stage];
3168 const struct wined3d_gl_info *gl_info = context->gl_info;
3169 DWORD op, arg1, arg2, arg0;
3171 TRACE("Setting alpha op for stage %d\n", stage);
3172 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3173 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3175 if (tex_used && mapped_stage >= gl_info->limits.textures)
3177 FIXME("Attempt to enable unsupported stage!\n");
3178 return;
3180 context_active_texture(context, gl_info, mapped_stage);
3183 op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3184 arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3185 arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3186 arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3188 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3190 struct wined3d_texture *texture = state->textures[0];
3191 GLenum texture_dimensions = texture->target;
3193 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3195 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3197 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3199 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3200 * properly. On the other hand applications can still use texture combiners apparently. This code
3201 * takes care that apps cannot remove the texture's alpha channel entirely.
3203 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3204 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3205 * and alpha component of diffuse color to draw things like translucent text and perform other
3206 * blending effects.
3208 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3209 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3210 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3211 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3212 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3213 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3214 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3215 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3216 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3217 * alpha.
3219 * What to do with multitexturing? So far no app has been found that uses color keying with
3220 * multitexturing */
3221 if (op == WINED3D_TOP_DISABLE)
3223 arg1 = WINED3DTA_TEXTURE;
3224 op = WINED3D_TOP_SELECT_ARG1;
3226 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3228 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3230 arg2 = WINED3DTA_TEXTURE;
3231 op = WINED3D_TOP_MODULATE;
3233 else arg1 = WINED3DTA_TEXTURE;
3235 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3237 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3239 arg1 = WINED3DTA_TEXTURE;
3240 op = WINED3D_TOP_MODULATE;
3242 else arg2 = WINED3DTA_TEXTURE;
3248 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3249 * this if block here, and the other code(color keying, texture unit selection) are the same
3251 TRACE("Setting alpha op for stage %d\n", stage);
3252 if (gl_info->supported[NV_REGISTER_COMBINERS])
3254 set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3255 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3257 else
3259 set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3263 static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3265 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3266 const struct wined3d_device *device = context->swapchain->device;
3267 const struct wined3d_gl_info *gl_info = context->gl_info;
3268 DWORD mapped_stage = device->texUnitMap[texUnit];
3269 BOOL generated;
3270 int coordIdx;
3272 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3273 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3275 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3276 return;
3279 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3280 if (mapped_stage >= gl_info->limits.textures) return;
3282 context_active_texture(context, gl_info, mapped_stage);
3283 generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3284 coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3286 set_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3287 state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3288 generated, context->last_was_rhw,
3289 device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3290 ? device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3291 : WINED3DFMT_UNKNOWN,
3292 device->frag_pipe->ffp_proj_control);
3294 /* The sampler applying function calls us if this changes */
3295 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3297 if(generated) {
3298 FIXME("Non-power2 texture being used with generated texture coords\n");
3300 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3301 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3302 if (!use_ps(state))
3304 TRACE("Non power two matrix multiply fixup\n");
3305 glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3310 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3312 unsigned int texture_idx;
3314 for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3316 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3317 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3321 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3322 GLuint *curVBO, const struct wined3d_state *state)
3324 const struct wined3d_device *device = context->swapchain->device;
3325 const struct wined3d_gl_info *gl_info = context->gl_info;
3326 unsigned int mapped_stage = 0;
3327 unsigned int textureNo = 0;
3329 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3331 int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3333 mapped_stage = device->texUnitMap[textureNo];
3334 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3336 if (mapped_stage >= gl_info->limits.texture_coords)
3338 FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3339 continue;
3342 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3344 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3346 TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3347 textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3349 if (*curVBO != e->data.buffer_object)
3351 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3352 checkGLcall("glBindBufferARB");
3353 *curVBO = e->data.buffer_object;
3356 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3357 checkGLcall("glClientActiveTextureARB");
3359 /* The coords to supply depend completely on the fvf / vertex shader */
3360 glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3361 e->data.addr + state->load_base_vertex_index * e->stride);
3362 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3364 else
3366 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3369 if (gl_info->supported[NV_REGISTER_COMBINERS])
3371 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3372 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3374 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3378 checkGLcall("loadTexCoords");
3381 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3383 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3384 const struct wined3d_device *device = context->swapchain->device;
3385 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3386 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3387 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3388 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3389 const struct wined3d_gl_info *gl_info = context->gl_info;
3390 DWORD mapped_stage = device->texUnitMap[stage];
3392 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3394 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3395 return;
3398 if (mapped_stage >= gl_info->limits.fragment_samplers)
3400 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3401 return;
3403 context_active_texture(context, gl_info, mapped_stage);
3405 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3407 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3408 * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3409 * means use the vertex position (camera-space) as the input texture coordinates
3410 * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3411 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3412 * to the TEXCOORDINDEX value
3414 switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3416 case WINED3DTSS_TCI_PASSTHRU:
3417 /* Use the specified texture coordinates contained within the
3418 * vertex format. This value resolves to zero. */
3419 glDisable(GL_TEXTURE_GEN_S);
3420 glDisable(GL_TEXTURE_GEN_T);
3421 glDisable(GL_TEXTURE_GEN_R);
3422 glDisable(GL_TEXTURE_GEN_Q);
3423 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3424 break;
3426 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3427 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3428 * as the input texture coordinates for this stage's texture transformation. This
3429 * equates roughly to EYE_LINEAR */
3431 glMatrixMode(GL_MODELVIEW);
3432 glPushMatrix();
3433 glLoadIdentity();
3434 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3435 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3436 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3437 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3438 glPopMatrix();
3439 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3441 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3442 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3443 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3444 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3446 glEnable(GL_TEXTURE_GEN_S);
3447 glEnable(GL_TEXTURE_GEN_T);
3448 glEnable(GL_TEXTURE_GEN_R);
3449 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3451 break;
3453 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3454 /* Note that NV_TEXGEN_REFLECTION support is implied when
3455 * ARB_TEXTURE_CUBE_MAP is supported */
3456 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3458 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3459 break;
3462 glMatrixMode(GL_MODELVIEW);
3463 glPushMatrix();
3464 glLoadIdentity();
3465 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3466 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3467 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3468 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3469 glPopMatrix();
3470 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3472 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3473 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3474 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3475 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3477 glEnable(GL_TEXTURE_GEN_S);
3478 glEnable(GL_TEXTURE_GEN_T);
3479 glEnable(GL_TEXTURE_GEN_R);
3480 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3482 break;
3484 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3485 /* Note that NV_TEXGEN_REFLECTION support is implied when
3486 * ARB_TEXTURE_CUBE_MAP is supported */
3487 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3489 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3490 break;
3493 glMatrixMode(GL_MODELVIEW);
3494 glPushMatrix();
3495 glLoadIdentity();
3496 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3497 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3498 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3499 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3500 glPopMatrix();
3501 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3503 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3504 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3505 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3506 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3508 glEnable(GL_TEXTURE_GEN_S);
3509 glEnable(GL_TEXTURE_GEN_T);
3510 glEnable(GL_TEXTURE_GEN_R);
3511 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3513 break;
3515 case WINED3DTSS_TCI_SPHEREMAP:
3516 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3517 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3518 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3520 glEnable(GL_TEXTURE_GEN_S);
3521 glEnable(GL_TEXTURE_GEN_T);
3522 glDisable(GL_TEXTURE_GEN_R);
3523 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3525 break;
3527 default:
3528 FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3529 state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3530 glDisable(GL_TEXTURE_GEN_S);
3531 glDisable(GL_TEXTURE_GEN_T);
3532 glDisable(GL_TEXTURE_GEN_R);
3533 glDisable(GL_TEXTURE_GEN_Q);
3534 checkGLcall("Disable texgen.");
3536 break;
3539 /* Update the texture matrix. */
3540 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3541 transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3543 if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3545 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3546 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3547 * and do all the things linked to it
3548 * TODO: Tidy that up to reload only the arrays of the changed unit
3550 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3552 unload_tex_coords(gl_info);
3553 load_tex_coords(context, &device->strided_streams, &curVBO, state);
3557 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3559 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3560 const struct wined3d_shader *ps = state->pixel_shader;
3562 if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3564 /* The pixel shader has to know the luminance scale. Do a constants
3565 * update if it isn't scheduled anyway. */
3566 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3567 && !isStateDirty(context, STATE_PIXELSHADER))
3568 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3572 static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3574 const DWORD sampler = state_id - STATE_SAMPLER(0);
3575 const struct wined3d_texture *texture = state->textures[sampler];
3577 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3579 if(!texture) return;
3580 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3581 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3582 * scaling is reapplied or removed, the texture matrix has to be reapplied
3584 * The mapped stage is already active because the sampler() function below, which is part of the
3585 * misc pipeline
3587 if (sampler < MAX_TEXTURES)
3589 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3591 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3593 const struct wined3d_device *device = context->swapchain->device;
3595 if (texIsPow2)
3596 context->lastWasPow2Texture |= 1 << sampler;
3597 else
3598 context->lastWasPow2Texture &= ~(1 << sampler);
3600 transform_texture(context, state,
3601 STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3606 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3608 const struct wined3d_device *device = context->swapchain->device;
3609 DWORD sampler = state_id - STATE_SAMPLER(0);
3610 DWORD mapped_stage = device->texUnitMap[sampler];
3611 const struct wined3d_gl_info *gl_info = context->gl_info;
3612 union {
3613 float f;
3614 DWORD d;
3615 } tmpvalue;
3617 TRACE("Sampler: %d\n", sampler);
3618 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3619 * only has to bind textures and set the per texture states
3622 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3624 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3625 return;
3628 if (mapped_stage >= gl_info->limits.combined_samplers)
3630 return;
3632 context_active_texture(context, gl_info, mapped_stage);
3634 if (state->textures[sampler])
3636 struct wined3d_texture *texture = state->textures[sampler];
3637 BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3639 texture->texture_ops->texture_bind(texture, context, srgb);
3640 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3642 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3644 tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3645 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3646 GL_TEXTURE_LOD_BIAS_EXT,
3647 tmpvalue.f);
3648 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3651 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3653 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3655 /* If color keying is enabled update the alpha test, it
3656 * depends on the existence of a color key in stage 0. */
3657 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3661 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3662 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3663 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3665 else
3667 if (sampler < state->lowest_disabled_stage)
3669 /* TODO: What should I do with pixel shaders here ??? */
3670 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3672 /* If color keying is enabled update the alpha test, it
3673 * depends on the existence of a color key in stage 0. */
3674 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3676 } /* Otherwise tex_colorop disables the stage */
3677 context_bind_texture(context, GL_NONE, 0);
3681 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3683 const struct wined3d_device *device = context->swapchain->device;
3684 BOOL use_vshader = use_vs(state);
3685 BOOL use_pshader = use_ps(state);
3686 unsigned int i;
3688 if (use_pshader)
3690 if (!context->last_was_pshader)
3692 /* Former draw without a pixel shader, some samplers may be
3693 * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3694 * make sure to enable them. */
3695 for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3697 if (!isStateDirty(context, STATE_SAMPLER(i)))
3698 sampler(context, state, STATE_SAMPLER(i));
3700 context->last_was_pshader = TRUE;
3702 else
3704 /* Otherwise all samplers were activated by the code above in
3705 * earlier draws, or by sampler() if a different texture was
3706 * bound. I don't have to do anything. */
3709 else
3711 /* Disabled the pixel shader - color ops weren't applied while it was
3712 * enabled, so re-apply them. */
3713 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3715 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3716 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3718 context->last_was_pshader = FALSE;
3721 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
3723 device->shader_backend->shader_select(context, use_pshader, use_vshader);
3725 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader))
3726 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
3730 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3732 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3733 const struct wined3d_shader *ps = state->pixel_shader;
3735 if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3737 /* The pixel shader has to know the bump env matrix. Do a constants
3738 * update if it isn't scheduled anyway. */
3739 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3740 && !isStateDirty(context, STATE_PIXELSHADER))
3741 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3745 static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3747 /* This function is called by transform_view below if the view matrix was changed too
3749 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3750 * does not always update the world matrix, only on a switch between transformed
3751 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3752 * draw, but that should be rather rare and cheaper in total.
3754 glMatrixMode(GL_MODELVIEW);
3755 checkGLcall("glMatrixMode");
3757 if(context->last_was_rhw) {
3758 glLoadIdentity();
3759 checkGLcall("glLoadIdentity()");
3761 else
3763 /* In the general case, the view matrix is the identity matrix */
3764 if (context->swapchain->device->view_ident)
3766 glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3767 checkGLcall("glLoadMatrixf");
3769 else
3771 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3772 checkGLcall("glLoadMatrixf");
3773 glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3774 checkGLcall("glMultMatrixf");
3779 static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3781 UINT index = state_id - STATE_CLIPPLANE(0);
3783 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= context->gl_info->limits.clipplanes)
3784 return;
3786 glMatrixMode(GL_MODELVIEW);
3787 glPushMatrix();
3789 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3790 if (!use_vs(state))
3791 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3792 else
3793 /* with vertex shaders, clip planes are not transformed in direct3d,
3794 * in OpenGL they are still transformed by the model view.
3796 glLoadIdentity();
3798 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3799 state->clip_planes[index][0],
3800 state->clip_planes[index][1],
3801 state->clip_planes[index][2],
3802 state->clip_planes[index][3]);
3803 glClipPlane(GL_CLIP_PLANE0 + index, state->clip_planes[index]);
3804 checkGLcall("glClipPlane");
3806 glPopMatrix();
3809 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3811 UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3812 GLenum glMat;
3813 TRACE("Setting world matrix %d\n", matrix);
3815 if (matrix >= context->gl_info->limits.blends)
3817 WARN("Unsupported blend matrix set\n");
3818 return;
3821 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3822 return;
3824 /* GL_MODELVIEW0_ARB: 0x1700
3825 * GL_MODELVIEW1_ARB: 0x850a
3826 * GL_MODELVIEW2_ARB: 0x8722
3827 * GL_MODELVIEW3_ARB: 0x8723
3828 * etc
3829 * GL_MODELVIEW31_ARB: 0x873F
3831 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3832 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3834 glMatrixMode(glMat);
3835 checkGLcall("glMatrixMode(glMat)");
3837 /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3838 * matrices while gl uses only 2. To avoid weighting the view matrix
3839 * incorrectly it has to be multiplied into every GL modelview matrix. */
3840 if (context->swapchain->device->view_ident)
3842 glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3843 checkGLcall("glLoadMatrixf");
3845 else
3847 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3848 checkGLcall("glLoadMatrixf");
3849 glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3850 checkGLcall("glMultMatrixf");
3854 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3856 enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3857 static unsigned int once;
3859 if (f == WINED3D_VBF_DISABLE)
3860 return;
3862 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3863 else WARN("Vertex blend flags %#x not supported.\n", f);
3866 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3868 enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3869 struct wined3d_device *device = context->swapchain->device;
3870 const struct wined3d_gl_info *gl_info = context->gl_info;
3871 static unsigned int once;
3873 switch (val)
3875 case WINED3D_VBF_1WEIGHTS:
3876 case WINED3D_VBF_2WEIGHTS:
3877 case WINED3D_VBF_3WEIGHTS:
3878 glEnable(GL_VERTEX_BLEND_ARB);
3879 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3881 /* D3D adds one more matrix which has weight (1 - sum(weights)).
3882 * This is enabled at context creation with enabling
3883 * GL_WEIGHT_SUM_UNITY_ARB. */
3884 GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3886 if (!device->vertexBlendUsed)
3888 unsigned int i;
3889 for (i = 1; i < gl_info->limits.blends; ++i)
3891 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3892 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3894 device->vertexBlendUsed = TRUE;
3896 break;
3898 case WINED3D_VBF_TWEENING:
3899 case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3900 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3901 else WARN("Vertex blend flags %#x not supported.\n", val);
3902 /* Fall through. */
3903 case WINED3D_VBF_DISABLE:
3904 glDisable(GL_VERTEX_BLEND_ARB);
3905 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3906 break;
3910 static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3912 const struct wined3d_gl_info *gl_info = context->gl_info;
3913 const struct wined3d_light_info *light = NULL;
3914 unsigned int k;
3916 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3917 * NOTE: We have to reset the positions even if the light/plane is not currently
3918 * enabled, since the call to enable it will not reset the position.
3919 * NOTE2: Apparently texture transforms do NOT need reapplying
3922 glMatrixMode(GL_MODELVIEW);
3923 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3924 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3925 checkGLcall("glLoadMatrixf(...)");
3927 /* Reset lights. TODO: Call light apply func */
3928 for (k = 0; k < gl_info->limits.lights; ++k)
3930 if (!(light = state->lights[k]))
3931 continue;
3932 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3933 checkGLcall("glLightfv posn");
3934 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3935 checkGLcall("glLightfv dirn");
3938 /* Reset Clipping Planes */
3939 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3941 if (!isStateDirty(context, STATE_CLIPPLANE(k)))
3942 clipplane(context, state, STATE_CLIPPLANE(k));
3945 if(context->last_was_rhw) {
3946 glLoadIdentity();
3947 checkGLcall("glLoadIdentity()");
3948 /* No need to update the world matrix, the identity is fine */
3949 return;
3952 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3953 * No need to do it here if the state is scheduled for update. */
3954 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
3955 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
3957 /* Avoid looping over a number of matrices if the app never used the functionality */
3958 if (context->swapchain->device->vertexBlendUsed)
3960 for (k = 1; k < gl_info->limits.blends; ++k)
3962 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
3963 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
3968 static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3970 glMatrixMode(GL_PROJECTION);
3971 checkGLcall("glMatrixMode(GL_PROJECTION)");
3973 /* There are a couple of additional things we have to take into account
3974 * here besides the projection transformation itself:
3975 * - We need to flip along the y-axis in case of offscreen rendering.
3976 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
3977 * - D3D coordinates refer to pixel centers while GL coordinates refer
3978 * to pixel corners.
3979 * - D3D has a top-left filling convention. We need to maintain this
3980 * even after the y-flip mentioned above.
3981 * In order to handle the last two points, we translate by
3982 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
3983 * translating slightly less than half a pixel. We want the difference to
3984 * be large enough that it doesn't get lost due to rounding inside the
3985 * driver, but small enough to prevent it from interfering with any
3986 * anti-aliasing. */
3988 if (context->last_was_rhw)
3990 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
3991 double x = state->viewport.x;
3992 double y = state->viewport.y;
3993 double w = state->viewport.width;
3994 double h = state->viewport.height;
3995 double x_scale = 2.0 / w;
3996 double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
3997 double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
3998 double y_offset = context->render_offscreen
3999 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
4000 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
4001 const GLdouble projection[] =
4003 x_scale, 0.0, 0.0, 0.0,
4004 0.0, y_scale, 0.0, 0.0,
4005 0.0, 0.0, 2.0, 0.0,
4006 x_offset, y_offset, -1.0, 1.0,
4009 glLoadMatrixd(projection);
4010 checkGLcall("glLoadMatrixd");
4012 else
4014 double y_scale = context->render_offscreen ? -1.0 : 1.0;
4015 double x_offset = (63.0 / 64.0) / state->viewport.width;
4016 double y_offset = context->render_offscreen
4017 ? (63.0 / 64.0) / state->viewport.height
4018 : -(63.0 / 64.0) / state->viewport.height;
4019 const GLdouble projection[] =
4021 1.0, 0.0, 0.0, 0.0,
4022 0.0, y_scale, 0.0, 0.0,
4023 0.0, 0.0, 2.0, 0.0,
4024 x_offset, y_offset, -1.0, 1.0,
4027 glLoadMatrixd(projection);
4028 checkGLcall("glLoadMatrixd");
4030 glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4031 checkGLcall("glLoadMatrixf");
4035 /* This should match any arrays loaded in load_vertex_data.
4036 * TODO: Only load / unload arrays if we have to. */
4037 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4039 glDisableClientState(GL_VERTEX_ARRAY);
4040 glDisableClientState(GL_NORMAL_ARRAY);
4041 glDisableClientState(GL_COLOR_ARRAY);
4042 if (gl_info->supported[EXT_SECONDARY_COLOR])
4044 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4046 if (gl_info->supported[ARB_VERTEX_BLEND])
4048 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4050 unload_tex_coords(gl_info);
4053 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4055 const struct wined3d_gl_info *gl_info = context->gl_info;
4057 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4058 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4060 context->numbered_array_mask &= ~(1 << i);
4063 /* This should match any arrays loaded in loadNumberedArrays
4064 * TODO: Only load / unload arrays if we have to. */
4065 static void unload_numbered_arrays(struct wined3d_context *context)
4067 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4068 int i;
4070 for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4071 unload_numbered_array(context, i);
4075 static void load_numbered_arrays(struct wined3d_context *context,
4076 const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4078 struct wined3d_device *device = context->swapchain->device;
4079 const struct wined3d_gl_info *gl_info = context->gl_info;
4080 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4081 int i;
4083 /* Default to no instancing */
4084 device->instancedDraw = FALSE;
4086 for (i = 0; i < MAX_ATTRIBS; i++)
4088 const struct wined3d_stream_state *stream;
4090 if (!(stream_info->use_map & (1 << i)))
4092 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4093 continue;
4096 stream = &state->streams[stream_info->elements[i].stream_idx];
4098 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4099 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4101 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4102 device->instancedDraw = TRUE;
4103 continue;
4106 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4108 if (stream_info->elements[i].stride)
4110 if (curVBO != stream_info->elements[i].data.buffer_object)
4112 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4113 checkGLcall("glBindBufferARB");
4114 curVBO = stream_info->elements[i].data.buffer_object;
4116 /* Use the VBO to find out if a vertex buffer exists, not the vb
4117 * pointer. vb can point to a user pointer data blob. In that case
4118 * curVBO will be 0. If there is a vertex buffer but no vbo we
4119 * won't be load converted attributes anyway. */
4120 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4121 stream_info->elements[i].format->gl_vtx_type,
4122 stream_info->elements[i].format->gl_normalized,
4123 stream_info->elements[i].stride, stream_info->elements[i].data.addr
4124 + state->load_base_vertex_index * stream_info->elements[i].stride));
4126 if (!(context->numbered_array_mask & (1 << i)))
4128 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4129 context->numbered_array_mask |= (1 << i);
4132 else
4134 /* Stride = 0 means always the same values.
4135 * glVertexAttribPointerARB doesn't do that. Instead disable the
4136 * pointer and set up the attribute statically. But we have to
4137 * figure out the system memory address. */
4138 const BYTE *ptr = stream_info->elements[i].data.addr;
4139 if (stream_info->elements[i].data.buffer_object)
4141 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4144 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4146 switch (stream_info->elements[i].format->id)
4148 case WINED3DFMT_R32_FLOAT:
4149 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4150 break;
4151 case WINED3DFMT_R32G32_FLOAT:
4152 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4153 break;
4154 case WINED3DFMT_R32G32B32_FLOAT:
4155 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4156 break;
4157 case WINED3DFMT_R32G32B32A32_FLOAT:
4158 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4159 break;
4161 case WINED3DFMT_R8G8B8A8_UINT:
4162 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4163 break;
4164 case WINED3DFMT_B8G8R8A8_UNORM:
4165 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4167 const DWORD *src = (const DWORD *)ptr;
4168 DWORD c = *src & 0xff00ff00;
4169 c |= (*src & 0xff0000) >> 16;
4170 c |= (*src & 0xff) << 16;
4171 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4172 break;
4174 /* else fallthrough */
4175 case WINED3DFMT_R8G8B8A8_UNORM:
4176 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4177 break;
4179 case WINED3DFMT_R16G16_SINT:
4180 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4181 break;
4182 case WINED3DFMT_R16G16B16A16_SINT:
4183 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4184 break;
4186 case WINED3DFMT_R16G16_SNORM:
4188 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4189 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4190 break;
4192 case WINED3DFMT_R16G16_UNORM:
4194 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4195 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4196 break;
4198 case WINED3DFMT_R16G16B16A16_SNORM:
4199 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4200 break;
4201 case WINED3DFMT_R16G16B16A16_UNORM:
4202 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4203 break;
4205 case WINED3DFMT_R10G10B10A2_UINT:
4206 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4207 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4208 break;
4209 case WINED3DFMT_R10G10B10A2_SNORM:
4210 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4211 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4212 break;
4214 case WINED3DFMT_R16G16_FLOAT:
4215 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4216 * byte float according to the IEEE standard
4218 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4219 break;
4220 case WINED3DFMT_R16G16B16A16_FLOAT:
4221 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4222 break;
4224 default:
4225 ERR("Unexpected declaration in stride 0 attributes\n");
4226 break;
4231 checkGLcall("Loading numbered arrays");
4234 static void load_vertex_data(const struct wined3d_context *context,
4235 const struct wined3d_stream_info *si, const struct wined3d_state *state)
4237 struct wined3d_device *device = context->swapchain->device;
4238 const struct wined3d_gl_info *gl_info = context->gl_info;
4239 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4240 const struct wined3d_stream_info_element *e;
4242 TRACE("Using fast vertex array code\n");
4244 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4245 device->instancedDraw = FALSE;
4247 /* Blend Data ---------------------------------------------- */
4248 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4249 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4251 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4253 if (gl_info->supported[ARB_VERTEX_BLEND])
4255 TRACE("Blend %u %p %u\n", e->format->component_count,
4256 e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4258 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4259 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4261 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4263 if (curVBO != e->data.buffer_object)
4265 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4266 checkGLcall("glBindBufferARB");
4267 curVBO = e->data.buffer_object;
4270 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4271 e->format->gl_vtx_format,
4272 e->format->gl_vtx_type,
4273 e->stride,
4274 e->data.addr + state->load_base_vertex_index * e->stride);
4275 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4276 e->data.addr + state->load_base_vertex_index * e->stride));
4278 checkGLcall("glWeightPointerARB");
4280 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4282 static BOOL warned;
4283 if (!warned)
4285 FIXME("blendMatrixIndices support\n");
4286 warned = TRUE;
4289 } else {
4290 /* TODO: support blends in drawStridedSlow
4291 * No need to write a FIXME here, this is done after the general vertex decl decoding
4293 WARN("unsupported blending in openGl\n");
4296 else
4298 if (gl_info->supported[ARB_VERTEX_BLEND])
4300 static const GLbyte one = 1;
4301 GL_EXTCALL(glWeightbvARB(1, &one));
4302 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4306 /* Point Size ----------------------------------------------*/
4307 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4309 /* no such functionality in the fixed function GL pipeline */
4310 TRACE("Cannot change ptSize here in openGl\n");
4311 /* TODO: Implement this function in using shaders if they are available */
4314 /* Vertex Pointers -----------------------------------------*/
4315 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4317 e = &si->elements[WINED3D_FFP_POSITION];
4319 if (curVBO != e->data.buffer_object)
4321 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4322 checkGLcall("glBindBufferARB");
4323 curVBO = e->data.buffer_object;
4326 /* min(WINED3D_ATR_FORMAT(position),3) to Disable RHW mode as 'w' coord
4327 handling for rhw mode should not impact screen position whereas in GL it does.
4328 This may result in very slightly distorted textures in rhw mode.
4329 There's always the other option of fixing the view matrix to
4330 prevent w from having any effect.
4332 This only applies to user pointer sources, in VBOs the vertices are fixed up
4334 if (!e->data.buffer_object)
4336 TRACE("glVertexPointer(3, %#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4337 e->data.addr + state->load_base_vertex_index * e->stride);
4338 glVertexPointer(3 /* min(e->format->gl_vtx_format, 3) */, e->format->gl_vtx_type, e->stride,
4339 e->data.addr + state->load_base_vertex_index * e->stride);
4341 else
4343 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4344 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4345 e->data.addr + state->load_base_vertex_index * e->stride);
4346 glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4347 e->data.addr + state->load_base_vertex_index * e->stride);
4349 checkGLcall("glVertexPointer(...)");
4350 glEnableClientState(GL_VERTEX_ARRAY);
4351 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4354 /* Normals -------------------------------------------------*/
4355 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4357 e = &si->elements[WINED3D_FFP_NORMAL];
4359 if (curVBO != e->data.buffer_object)
4361 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4362 checkGLcall("glBindBufferARB");
4363 curVBO = e->data.buffer_object;
4366 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4367 e->data.addr + state->load_base_vertex_index * e->stride);
4368 glNormalPointer(e->format->gl_vtx_type, e->stride,
4369 e->data.addr + state->load_base_vertex_index * e->stride);
4370 checkGLcall("glNormalPointer(...)");
4371 glEnableClientState(GL_NORMAL_ARRAY);
4372 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4374 } else {
4375 glNormal3f(0, 0, 0);
4376 checkGLcall("glNormal3f(0, 0, 0)");
4379 /* Diffuse Colour --------------------------------------------*/
4380 /* WARNING: Data here MUST be in RGBA format, so cannot */
4381 /* go directly into fast mode from app pgm, because */
4382 /* directx requires data in BGRA format. */
4383 /* currently fixupVertices swizzles the format, but this isn't*/
4384 /* very practical when using VBOs */
4385 /* NOTE: Unless we write a vertex shader to swizzle the colour*/
4386 /* , or the user doesn't care and wants the speed advantage */
4388 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4390 e = &si->elements[WINED3D_FFP_DIFFUSE];
4392 if (curVBO != e->data.buffer_object)
4394 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4395 checkGLcall("glBindBufferARB");
4396 curVBO = e->data.buffer_object;
4399 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4400 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4401 e->data.addr + state->load_base_vertex_index * e->stride);
4402 glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4403 e->data.addr + state->load_base_vertex_index * e->stride);
4404 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4405 glEnableClientState(GL_COLOR_ARRAY);
4406 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4408 } else {
4409 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4410 checkGLcall("glColor4f(1, 1, 1, 1)");
4413 /* Specular Colour ------------------------------------------*/
4414 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4416 TRACE("setting specular colour\n");
4418 e = &si->elements[WINED3D_FFP_SPECULAR];
4420 if (gl_info->supported[EXT_SECONDARY_COLOR])
4422 GLenum type = e->format->gl_vtx_type;
4423 GLint format = e->format->gl_vtx_format;
4425 if (curVBO != e->data.buffer_object)
4427 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4428 checkGLcall("glBindBufferARB");
4429 curVBO = e->data.buffer_object;
4432 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4434 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4435 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4436 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4437 * 4 component secondary colors use it
4439 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4440 e->data.addr + state->load_base_vertex_index * e->stride);
4441 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4442 e->data.addr + state->load_base_vertex_index * e->stride));
4443 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4445 else
4447 switch(type)
4449 case GL_UNSIGNED_BYTE:
4450 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4451 e->data.addr + state->load_base_vertex_index * e->stride);
4452 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4453 e->data.addr + state->load_base_vertex_index * e->stride));
4454 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4455 break;
4457 default:
4458 FIXME("Add 4 component specular color pointers for type %x\n", type);
4459 /* Make sure that the right color component is dropped */
4460 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4461 e->data.addr + state->load_base_vertex_index * e->stride);
4462 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4463 e->data.addr + state->load_base_vertex_index * e->stride));
4464 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4467 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4468 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4470 else
4472 WARN("Specular colour is not supported in this GL implementation.\n");
4475 else
4477 if (gl_info->supported[EXT_SECONDARY_COLOR])
4479 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4480 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4482 else
4484 WARN("Specular colour is not supported in this GL implementation.\n");
4488 /* Texture coords -------------------------------------------*/
4489 load_tex_coords(context, si, &curVBO, state);
4492 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4494 const struct wined3d_device *device = context->swapchain->device;
4495 BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4496 BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4498 if (isStateDirty(context, STATE_VDECL)) return;
4499 if (context->numberedArraysLoaded && !load_numbered)
4501 unload_numbered_arrays(context);
4502 context->numberedArraysLoaded = FALSE;
4503 context->numbered_array_mask = 0;
4505 else if (context->namedArraysLoaded)
4507 unload_vertex_data(context->gl_info);
4508 context->namedArraysLoaded = FALSE;
4511 if (load_numbered)
4513 TRACE("Loading numbered arrays\n");
4514 load_numbered_arrays(context, &device->strided_streams, state);
4515 context->numberedArraysLoaded = TRUE;
4517 else if (load_named)
4519 TRACE("Loading vertex data\n");
4520 load_vertex_data(context, &device->strided_streams, state);
4521 context->namedArraysLoaded = TRUE;
4525 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4527 if (isStateDirty(context, STATE_STREAMSRC))
4528 return;
4529 streamsrc(context, state, STATE_STREAMSRC);
4532 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4534 const struct wined3d_device *device = context->swapchain->device;
4535 const struct wined3d_gl_info *gl_info = context->gl_info;
4536 BOOL useVertexShaderFunction = use_vs(state);
4537 BOOL usePixelShaderFunction = use_ps(state);
4538 BOOL updateFog = FALSE;
4539 BOOL transformed;
4540 BOOL wasrhw = context->last_was_rhw;
4541 unsigned int i;
4543 transformed = device->strided_streams.position_transformed;
4544 if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4545 updateFog = TRUE;
4547 context->last_was_rhw = transformed;
4549 /* Don't have to apply the matrices when vertex shaders are used. When
4550 * vshaders are turned off this function will be called again anyway to
4551 * make sure they're properly set. */
4552 if (!useVertexShaderFunction)
4554 /* TODO: Move this mainly to the viewport state and only apply when
4555 * the vp has changed or transformed / untransformed was switched. */
4556 if (wasrhw != context->last_was_rhw
4557 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4558 && !isStateDirty(context, STATE_VIEWPORT))
4559 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4560 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4561 * mode.
4563 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4564 * this check will fail and the matrix not applied again. This is OK because a simple
4565 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4566 * needs of the vertex declaration.
4568 * World and view matrix go into the same gl matrix, so only apply them when neither is
4569 * dirty
4571 if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4572 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4573 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4574 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4575 state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4576 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4577 state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4579 if (context->last_was_vshader)
4581 updateFog = TRUE;
4583 if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4584 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4586 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4588 clipplane(context, state, STATE_CLIPPLANE(i));
4591 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4592 state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4594 else
4596 if(!context->last_was_vshader) {
4597 static BOOL warned = FALSE;
4598 if(!device->vs_clipping) {
4599 /* Disable all clip planes to get defined results on all drivers. See comment in the
4600 * state_clipping state handler
4602 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4604 glDisable(GL_CLIP_PLANE0 + i);
4605 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4608 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4610 FIXME("Clipping not supported with vertex shaders\n");
4611 warned = TRUE;
4614 if (wasrhw)
4616 /* Apply the transform matrices when switching from rhw
4617 * drawing to vertex shaders. Vertex shaders themselves do
4618 * not need it, but the matrices are not reapplied
4619 * automatically when switching back from vertex shaders to
4620 * fixed function processing. So make sure we leave the fixed
4621 * function vertex processing states back in a sane state
4622 * before switching to shaders. */
4623 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4624 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4625 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4626 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4628 updateFog = TRUE;
4630 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4631 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4632 * device->vs_clipping is false.
4634 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4636 clipplane(context, state, STATE_CLIPPLANE(i));
4641 /* Vertex and pixel shaders are applied together, so let the last dirty
4642 * state do the application. */
4643 if (!isStateDirty(context, STATE_PIXELSHADER))
4645 device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4647 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)
4648 && (useVertexShaderFunction || usePixelShaderFunction))
4649 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4652 context->last_was_vshader = useVertexShaderFunction;
4654 if (updateFog)
4655 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4657 if (!useVertexShaderFunction)
4659 unsigned int i;
4661 for (i = 0; i < MAX_TEXTURES; ++i)
4663 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4664 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4668 if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4669 state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4672 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4674 const struct wined3d_surface *target = state->fb->render_targets[0];
4675 struct wined3d_viewport vp = state->viewport;
4677 if (vp.width > target->resource.width)
4678 vp.width = target->resource.width;
4679 if (vp.height > target->resource.height)
4680 vp.height = target->resource.height;
4682 glDepthRange(vp.min_z, vp.max_z);
4683 checkGLcall("glDepthRange");
4684 /* Note: GL requires lower left, DirectX supplies upper left. This is
4685 * reversed when using offscreen rendering. */
4686 if (context->render_offscreen)
4688 glViewport(vp.x, vp.y, vp.width, vp.height);
4690 else
4692 UINT width, height;
4694 target->get_drawable_size(context, &width, &height);
4695 glViewport(vp.x, (height - (vp.y + vp.height)),
4696 vp.width, vp.height);
4699 checkGLcall("glViewport");
4702 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4704 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4705 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4706 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4707 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4708 /* Update the position fixup. */
4709 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
4710 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4713 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4715 UINT Index = state_id - STATE_ACTIVELIGHT(0);
4716 const struct wined3d_light_info *lightInfo = state->lights[Index];
4718 if (!lightInfo)
4720 glDisable(GL_LIGHT0 + Index);
4721 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4723 else
4725 float quad_att;
4726 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4728 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4729 glMatrixMode(GL_MODELVIEW);
4730 glPushMatrix();
4731 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4733 /* Diffuse: */
4734 colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4735 colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4736 colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4737 colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4738 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4739 checkGLcall("glLightfv");
4741 /* Specular */
4742 colRGBA[0] = lightInfo->OriginalParms.specular.r;
4743 colRGBA[1] = lightInfo->OriginalParms.specular.g;
4744 colRGBA[2] = lightInfo->OriginalParms.specular.b;
4745 colRGBA[3] = lightInfo->OriginalParms.specular.a;
4746 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4747 checkGLcall("glLightfv");
4749 /* Ambient */
4750 colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4751 colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4752 colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4753 colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4754 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4755 checkGLcall("glLightfv");
4757 if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4758 quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4759 else
4760 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4762 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4763 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4764 * Attenuation0 to NaN and crashes in the gl lib
4767 switch (lightInfo->OriginalParms.type)
4769 case WINED3D_LIGHT_POINT:
4770 /* Position */
4771 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4772 checkGLcall("glLightfv");
4773 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4774 checkGLcall("glLightf");
4775 /* Attenuation - Are these right? guessing... */
4776 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4777 checkGLcall("glLightf");
4778 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4779 checkGLcall("glLightf");
4780 if (quad_att < lightInfo->OriginalParms.attenuation2)
4781 quad_att = lightInfo->OriginalParms.attenuation2;
4782 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4783 checkGLcall("glLightf");
4784 /* FIXME: Range */
4785 break;
4787 case WINED3D_LIGHT_SPOT:
4788 /* Position */
4789 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4790 checkGLcall("glLightfv");
4791 /* Direction */
4792 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4793 checkGLcall("glLightfv");
4794 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4795 checkGLcall("glLightf");
4796 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4797 checkGLcall("glLightf");
4798 /* Attenuation - Are these right? guessing... */
4799 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4800 checkGLcall("glLightf");
4801 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4802 checkGLcall("glLightf");
4803 if (quad_att < lightInfo->OriginalParms.attenuation2)
4804 quad_att = lightInfo->OriginalParms.attenuation2;
4805 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4806 checkGLcall("glLightf");
4807 /* FIXME: Range */
4808 break;
4810 case WINED3D_LIGHT_DIRECTIONAL:
4811 /* Direction */
4812 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4813 checkGLcall("glLightfv");
4814 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4815 checkGLcall("glLightf");
4816 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4817 checkGLcall("glLightf");
4818 break;
4820 default:
4821 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4824 /* Restore the modelview matrix */
4825 glPopMatrix();
4827 glEnable(GL_LIGHT0 + Index);
4828 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4832 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4834 const RECT *r = &state->scissor_rect;
4836 /* Warning: glScissor uses window coordinates, not viewport coordinates,
4837 * so our viewport correction does not apply. Warning2: Even in windowed
4838 * mode the coords are relative to the window, not the screen. */
4839 TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4841 if (context->render_offscreen)
4843 glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4845 else
4847 const struct wined3d_surface *target = state->fb->render_targets[0];
4848 UINT height;
4849 UINT width;
4851 target->get_drawable_size(context, &width, &height);
4852 glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4854 checkGLcall("glScissor");
4857 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4859 const struct wined3d_gl_info *gl_info = context->gl_info;
4861 if (state->user_stream || !state->index_buffer)
4863 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4865 else
4867 struct wined3d_buffer *ib = state->index_buffer;
4868 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4872 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4874 if (context->render_offscreen)
4876 glFrontFace(GL_CCW);
4877 checkGLcall("glFrontFace(GL_CCW)");
4878 } else {
4879 glFrontFace(GL_CW);
4880 checkGLcall("glFrontFace(GL_CW)");
4884 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4886 static BOOL warned;
4888 if (!warned)
4890 WARN("Point sprite coordinate origin switching not supported.\n");
4891 warned = TRUE;
4895 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4897 const struct wined3d_gl_info *gl_info = context->gl_info;
4898 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4900 if (glPointParameteri)
4902 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin);
4903 checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4905 else if (gl_info->supported[NV_POINT_SPRITE])
4907 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4908 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4912 const struct StateEntryTemplate misc_state_template[] = {
4913 { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4914 { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4915 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4916 { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4917 { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4918 { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4919 { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4920 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4921 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4922 { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4923 { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
4924 { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
4925 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4926 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4927 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4928 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4930 /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4931 * vshader loadings are untied from each other
4933 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4934 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4935 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4936 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4937 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4938 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4939 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4940 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4941 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4942 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4943 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4944 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4945 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4946 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4947 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4948 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4949 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4950 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4951 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4952 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4953 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4954 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4955 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4956 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4957 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4958 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4959 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4960 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4961 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4962 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4963 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4964 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4965 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4966 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4967 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4968 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4969 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4970 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4971 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4972 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4973 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4974 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4975 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4976 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4977 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4978 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4979 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4980 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4981 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4982 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4984 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
4985 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
4986 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
4987 { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
4988 { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
4989 { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
4990 { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
4991 { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
4992 { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
4993 { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
4994 { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
4995 { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
4996 { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
4997 { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
4998 { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
4999 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
5000 { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5001 { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5003 { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
5004 { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
5005 { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
5006 { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
5007 { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
5008 { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
5009 { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
5010 { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
5011 { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
5012 { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
5013 { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
5014 { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
5015 { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
5016 { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5017 { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5018 { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5019 { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5020 { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5021 { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5022 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
5023 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
5024 { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5025 { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5026 { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5027 { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5028 { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5029 { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5030 { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5031 { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5032 { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5033 { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5034 { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5035 { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5036 { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5037 { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5038 { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5039 { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5040 { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5042 { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5044 { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5045 { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5046 { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5047 { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5048 { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5050 { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5051 { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5052 { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5053 { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5054 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5055 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5056 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5057 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5058 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5059 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
5060 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5061 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5062 { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5063 { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5064 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5065 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5066 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5067 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5068 { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5069 { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5070 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5071 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5072 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5073 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5074 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5075 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5076 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5077 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5078 { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5079 { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5080 /* Samplers */
5081 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5082 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5083 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5084 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5085 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5086 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5087 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5088 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5089 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5090 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5091 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5092 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5093 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5094 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5095 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5096 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5097 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5098 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5099 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5100 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5101 { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
5102 { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
5103 { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
5104 { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
5105 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5108 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5109 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5110 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5111 { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5112 { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5113 /* Clip planes */
5114 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5115 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5116 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5117 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5118 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5119 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5120 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5121 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5122 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5123 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5124 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5125 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5126 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5127 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5128 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5129 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5130 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5131 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5132 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5133 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5134 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5135 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5136 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5137 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5138 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5139 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5140 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5141 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5142 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5143 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5144 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5145 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5146 /* Lights */
5147 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5148 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5149 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5150 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5151 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5152 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5153 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5154 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5155 /* Viewport */
5156 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5157 /* Transform states follow */
5158 { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5159 { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5160 { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5161 { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5162 { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5163 { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5164 { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5165 { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5166 { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5167 { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5168 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5169 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5170 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5171 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5172 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5173 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5174 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5175 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5176 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5177 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5178 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5179 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5180 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5181 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5182 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5183 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5184 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5185 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5186 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5187 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5188 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5189 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5190 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5191 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5192 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5193 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5194 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5195 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5396 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5397 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5400 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5401 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5402 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5403 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5405 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5406 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5407 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5411 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5412 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5413 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5414 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5415 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5416 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5417 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5418 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5419 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5420 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5421 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5422 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5423 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5424 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5425 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5426 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5427 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5428 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5429 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5430 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5431 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5432 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5433 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5434 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5435 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5436 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5437 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5438 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5439 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5440 /* Fog */
5441 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5442 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5443 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5444 { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5445 { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5446 { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5447 { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5448 { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5449 { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5450 { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5451 { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5452 { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5453 { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5454 { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5455 { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5456 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5457 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5458 { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5459 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5460 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5461 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5462 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5463 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5464 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5465 { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5466 { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5467 { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5468 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5469 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5470 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5471 { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5472 { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5474 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5475 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5476 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5478 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5479 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5480 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5481 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5482 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5483 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5484 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5485 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5486 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5487 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5488 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5489 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5490 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5491 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5492 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5493 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5494 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5495 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5496 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5497 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5498 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5499 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5500 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5501 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5502 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5505 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5506 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5507 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5508 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5509 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5510 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5511 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5512 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5513 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5514 { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5515 { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5516 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5517 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5518 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5519 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5520 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5521 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5522 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5523 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5524 { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5525 { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5526 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5527 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5528 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5529 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5530 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5531 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5532 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5533 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5534 { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5535 { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5536 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5537 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5538 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5539 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5540 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5541 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5542 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5543 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5544 { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5545 { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5546 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5547 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5548 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5549 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5550 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5551 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5552 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5553 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5554 { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5555 { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5556 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5557 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5558 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5559 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5560 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5561 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5562 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5563 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5564 { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5565 { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5566 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5567 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5568 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5569 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5570 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5571 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5572 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5573 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5574 { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5575 { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5576 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5577 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5578 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5579 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5580 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5581 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5582 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5583 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5584 { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5585 { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5586 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5587 { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5588 { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5589 { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5590 { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5591 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5592 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5593 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5594 { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5595 { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5596 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5597 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5598 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5599 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5600 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5601 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5602 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5603 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5604 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5607 /* Context activation and GL locking are done by the caller. */
5608 static void ffp_enable(BOOL enable) {}
5610 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5612 caps->PrimitiveMiscCaps = 0;
5613 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5614 | WINED3DTEXOPCAPS_ADDSIGNED
5615 | WINED3DTEXOPCAPS_ADDSIGNED2X
5616 | WINED3DTEXOPCAPS_MODULATE
5617 | WINED3DTEXOPCAPS_MODULATE2X
5618 | WINED3DTEXOPCAPS_MODULATE4X
5619 | WINED3DTEXOPCAPS_SELECTARG1
5620 | WINED3DTEXOPCAPS_SELECTARG2
5621 | WINED3DTEXOPCAPS_DISABLE;
5623 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5624 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5625 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5627 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5628 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5629 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5630 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5631 | WINED3DTEXOPCAPS_LERP
5632 | WINED3DTEXOPCAPS_SUBTRACT;
5634 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5635 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5637 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5638 | WINED3DTEXOPCAPS_MULTIPLYADD
5639 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5640 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5641 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5643 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5644 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5646 caps->MaxTextureBlendStages = gl_info->limits.textures;
5647 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5650 static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; }
5651 static void ffp_fragment_free(struct wined3d_device *device) {}
5652 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5654 if (TRACE_ON(d3d))
5656 TRACE("Checking support for fixup:\n");
5657 dump_color_fixup_desc(fixup);
5660 /* We only support identity conversions. */
5661 if (is_identity_fixup(fixup))
5663 TRACE("[OK]\n");
5664 return TRUE;
5667 TRACE("[FAILED]\n");
5668 return FALSE;
5671 const struct fragment_pipeline ffp_fragment_pipeline = {
5672 ffp_enable,
5673 ffp_fragment_get_caps,
5674 ffp_fragment_alloc,
5675 ffp_fragment_free,
5676 ffp_color_fixup_supported,
5677 ffp_fragmentstate_template,
5678 FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5681 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5683 unsigned int i;
5684 for(i = 0; funcs[i]; i++);
5685 return i;
5688 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5690 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5691 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5694 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5696 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5697 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5698 context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5701 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5703 unsigned int start, last, i;
5705 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5706 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5707 for (i = start; i <= last; ++i)
5709 state_table[i].representative = 0;
5710 state_table[i].apply = state_undefined;
5713 start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
5714 last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5715 for (i = start; i <= last; ++i)
5717 state_table[i].representative = 0;
5718 state_table[i].apply = state_undefined;
5721 start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5722 last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5723 for (i = start; i <= last; ++i)
5725 state_table[i].representative = 0;
5726 state_table[i].apply = state_undefined;
5730 static void validate_state_table(struct StateEntry *state_table)
5732 static const struct
5734 DWORD first;
5735 DWORD last;
5737 rs_holes[] =
5739 { 1, 1},
5740 { 3, 3},
5741 { 17, 18},
5742 { 21, 21},
5743 { 42, 45},
5744 { 47, 47},
5745 { 61, 127},
5746 {149, 150},
5747 {169, 169},
5748 {177, 177},
5749 {196, 197},
5750 { 0, 0},
5752 static const DWORD simple_states[] =
5754 STATE_MATERIAL,
5755 STATE_VDECL,
5756 STATE_STREAMSRC,
5757 STATE_INDEXBUFFER,
5758 STATE_VERTEXSHADERCONSTANT,
5759 STATE_PIXELSHADERCONSTANT,
5760 STATE_VSHADER,
5761 STATE_PIXELSHADER,
5762 STATE_VIEWPORT,
5763 STATE_SCISSORRECT,
5764 STATE_FRONTFACE,
5765 STATE_POINTSPRITECOORDORIGIN,
5766 STATE_BASEVERTEXINDEX,
5767 STATE_FRAMEBUFFER
5769 unsigned int i, current;
5771 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5773 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5775 if (!state_table[i].representative)
5776 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5778 else if (state_table[i].representative)
5779 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5781 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5784 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5786 if (!state_table[simple_states[i]].representative)
5787 ERR("State %s (%#x) should have a representative.\n",
5788 debug_d3dstate(simple_states[i]), simple_states[i]);
5791 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5793 DWORD rep = state_table[i].representative;
5794 if (rep)
5796 if (state_table[rep].representative != rep)
5798 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5799 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5800 state_table[i].representative = 0;
5803 if (rep != i)
5805 if (state_table[i].apply)
5806 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5808 else if (!state_table[i].apply)
5810 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5816 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5817 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5818 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5820 unsigned int i, type, handlers;
5821 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5822 const struct StateEntryTemplate *cur;
5823 BOOL set[STATE_HIGHEST + 1];
5825 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5827 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5828 StateTable[i].representative = 0;
5829 StateTable[i].apply = state_undefined;
5832 for(type = 0; type < 3; type++) {
5833 /* This switch decides the order in which the states are applied */
5834 switch(type) {
5835 case 0: cur = misc; break;
5836 case 1: cur = fragment->states; break;
5837 case 2: cur = vertex; break;
5838 default: cur = NULL; /* Stupid compiler */
5840 if(!cur) continue;
5842 /* GL extension filtering should not prevent multiple handlers being applied from different
5843 * pipeline parts
5845 memset(set, 0, sizeof(set));
5847 for(i = 0; cur[i].state; i++) {
5848 APPLYSTATEFUNC *funcs_array;
5850 /* Only use the first matching state with the available extension from one template.
5851 * e.g.
5852 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5853 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5855 * if GL_XYZ_fancy is supported, ignore the 2nd line
5857 if(set[cur[i].state]) continue;
5858 /* Skip state lines depending on unsupported extensions */
5859 if (!gl_info->supported[cur[i].extension]) continue;
5860 set[cur[i].state] = TRUE;
5861 /* In some cases having an extension means that nothing has to be
5862 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5863 * supported, the texture coordinate fixup can be ignored. If the
5864 * apply function is used, mark the state set(done above) to prevent
5865 * applying later lines, but do not record anything in the state
5866 * table
5868 if (!cur[i].content.representative) continue;
5870 handlers = num_handlers(multistate_funcs[cur[i].state]);
5871 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5872 switch(handlers) {
5873 case 0:
5874 StateTable[cur[i].state].apply = cur[i].content.apply;
5875 break;
5876 case 1:
5877 StateTable[cur[i].state].apply = multistate_apply_2;
5878 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5880 sizeof(**dev_multistate_funcs) * 2);
5881 if (!dev_multistate_funcs[cur[i].state]) {
5882 goto out_of_mem;
5885 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5886 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5887 break;
5888 case 2:
5889 StateTable[cur[i].state].apply = multistate_apply_3;
5890 funcs_array = HeapReAlloc(GetProcessHeap(),
5892 dev_multistate_funcs[cur[i].state],
5893 sizeof(**dev_multistate_funcs) * 3);
5894 if (!funcs_array) {
5895 goto out_of_mem;
5898 dev_multistate_funcs[cur[i].state] = funcs_array;
5899 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5900 break;
5901 default:
5902 ERR("Unexpected amount of state handlers for state %u: %u\n",
5903 cur[i].state, handlers + 1);
5906 if(StateTable[cur[i].state].representative &&
5907 StateTable[cur[i].state].representative != cur[i].content.representative) {
5908 FIXME("State %u has different representatives in different pipeline parts\n",
5909 cur[i].state);
5911 StateTable[cur[i].state].representative = cur[i].content.representative;
5915 prune_invalid_states(StateTable, gl_info);
5916 validate_state_table(StateTable);
5918 return WINED3D_OK;
5920 out_of_mem:
5921 for (i = 0; i <= STATE_HIGHEST; ++i) {
5922 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5925 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5927 return E_OUTOFMEMORY;