ddraw/tests: Add a test for the initial color keying state.
[wine/multimedia.git] / dlls / wined3d / state.c
blob8904aaa9d1af9d58deee8e8a2dcbfb550cc036cb
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 if (state->render_states[WINED3D_RS_ZWRITEENABLE])
210 glDepthMask(1);
211 checkGLcall("glDepthMask(1)");
213 else
215 glDepthMask(0);
216 checkGLcall("glDepthMask(0)");
220 static GLenum gl_compare_func(enum wined3d_cmp_func f)
222 switch (f)
224 case WINED3D_CMP_NEVER:
225 return GL_NEVER;
226 case WINED3D_CMP_LESS:
227 return GL_LESS;
228 case WINED3D_CMP_EQUAL:
229 return GL_EQUAL;
230 case WINED3D_CMP_LESSEQUAL:
231 return GL_LEQUAL;
232 case WINED3D_CMP_GREATER:
233 return GL_GREATER;
234 case WINED3D_CMP_NOTEQUAL:
235 return GL_NOTEQUAL;
236 case WINED3D_CMP_GREATEREQUAL:
237 return GL_GEQUAL;
238 case WINED3D_CMP_ALWAYS:
239 return GL_ALWAYS;
240 default:
241 FIXME("Unrecognized compare function %#x.\n", f);
242 return GL_NONE;
246 static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
248 GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
250 if (!depth_func) return;
252 if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL)
254 static BOOL once;
255 /* There are a few issues with this: First, our inability to
256 * select a proper Z depth, most of the time we're stuck with
257 * D24S8, even if the app selects D32 or D16. There seem to be
258 * some other precision problems which have to be debugged to
259 * make NOTEQUAL and EQUAL work properly. */
260 if (!once)
262 once = TRUE;
263 FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet.\n");
267 glDepthFunc(depth_func);
268 checkGLcall("glDepthFunc");
271 static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
273 float col[4];
275 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col);
276 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
277 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
278 checkGLcall("glLightModel for MODEL_AMBIENT");
281 static void state_blendop_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
283 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
286 static GLenum gl_blend_op(enum wined3d_blend_op op)
288 switch (op)
290 case WINED3D_BLEND_OP_ADD:
291 return GL_FUNC_ADD_EXT;
292 case WINED3D_BLEND_OP_SUBTRACT:
293 return GL_FUNC_SUBTRACT_EXT;
294 case WINED3D_BLEND_OP_REVSUBTRACT:
295 return GL_FUNC_REVERSE_SUBTRACT_EXT;
296 case WINED3D_BLEND_OP_MIN:
297 return GL_MIN_EXT;
298 case WINED3D_BLEND_OP_MAX:
299 return GL_MAX_EXT;
300 default:
301 FIXME("Unhandled blend op %#x.\n", op);
302 return GL_NONE;
306 static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
308 const struct wined3d_gl_info *gl_info = context->gl_info;
309 GLenum blend_equation_alpha = GL_FUNC_ADD_EXT;
310 GLenum blend_equation = GL_FUNC_ADD_EXT;
312 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
313 if (state->render_states[WINED3D_RS_BLENDOPALPHA]
314 && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
316 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
317 return;
320 blend_equation = gl_blend_op(state->render_states[WINED3D_RS_BLENDOP]);
321 blend_equation_alpha = gl_blend_op(state->render_states[WINED3D_RS_BLENDOPALPHA]);
322 TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
324 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
326 GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
327 checkGLcall("glBlendEquationSeparateEXT");
329 else
331 GL_EXTCALL(glBlendEquationEXT(blend_equation));
332 checkGLcall("glBlendEquation");
336 static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_format *dst_format)
338 switch (factor)
340 case WINED3D_BLEND_ZERO:
341 return GL_ZERO;
342 case WINED3D_BLEND_ONE:
343 return GL_ONE;
344 case WINED3D_BLEND_SRCCOLOR:
345 return GL_SRC_COLOR;
346 case WINED3D_BLEND_INVSRCCOLOR:
347 return GL_ONE_MINUS_SRC_COLOR;
348 case WINED3D_BLEND_SRCALPHA:
349 return GL_SRC_ALPHA;
350 case WINED3D_BLEND_INVSRCALPHA:
351 return GL_ONE_MINUS_SRC_ALPHA;
352 case WINED3D_BLEND_DESTCOLOR:
353 return GL_DST_COLOR;
354 case WINED3D_BLEND_INVDESTCOLOR:
355 return GL_ONE_MINUS_DST_COLOR;
356 /* To compensate for the lack of format switching with backbuffer
357 * offscreen rendering, and with onscreen rendering, we modify the
358 * alpha test parameters for (INV)DESTALPHA if the render target
359 * doesn't support alpha blending. A nonexistent alpha channel
360 * returns 1.0, so WINED3D_BLEND_DESTALPHA becomes GL_ONE, and
361 * WINED3D_BLEND_INVDESTALPHA becomes GL_ZERO. */
362 case WINED3D_BLEND_DESTALPHA:
363 return dst_format->alpha_mask ? GL_DST_ALPHA : GL_ONE;
364 case WINED3D_BLEND_INVDESTALPHA:
365 return dst_format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
366 case WINED3D_BLEND_SRCALPHASAT:
367 return GL_SRC_ALPHA_SATURATE;
368 case WINED3D_BLEND_BLENDFACTOR:
369 return GL_CONSTANT_COLOR_EXT;
370 case WINED3D_BLEND_INVBLENDFACTOR:
371 return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
372 default:
373 FIXME("Unhandled blend factor %#x.\n", factor);
374 return GL_NONE;
378 static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
380 const struct wined3d_surface *target = state->fb->render_targets[0];
381 const struct wined3d_gl_info *gl_info = context->gl_info;
382 GLenum srcBlend, dstBlend;
383 enum wined3d_blend d3d_blend;
385 /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
386 * blending parameters to work. */
387 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]
388 || state->render_states[WINED3D_RS_EDGEANTIALIAS]
389 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
391 /* Disable blending in all cases even without pixelshaders.
392 * With blending on we could face a big performance penalty.
393 * The d3d9 visual test confirms the behavior. */
394 if (context->render_offscreen
395 && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
397 glDisable(GL_BLEND);
398 checkGLcall("glDisable GL_BLEND");
399 return;
400 } else {
401 glEnable(GL_BLEND);
402 checkGLcall("glEnable GL_BLEND");
404 } else {
405 glDisable(GL_BLEND);
406 checkGLcall("glDisable GL_BLEND");
407 /* Nothing more to do - get out */
408 return;
411 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
412 * source blending values which are still valid up to d3d9. They should
413 * not occur as dest blend values. */
414 d3d_blend = state->render_states[WINED3D_RS_SRCBLEND];
415 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
417 srcBlend = GL_SRC_ALPHA;
418 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
420 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
422 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
423 dstBlend = GL_SRC_ALPHA;
425 else
427 srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
428 dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
429 target->resource.format);
432 if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
433 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
435 glEnable(GL_LINE_SMOOTH);
436 checkGLcall("glEnable(GL_LINE_SMOOTH)");
437 if(srcBlend != GL_SRC_ALPHA) {
438 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param\n");
440 if(dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE) {
441 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param\n");
443 } else {
444 glDisable(GL_LINE_SMOOTH);
445 checkGLcall("glDisable(GL_LINE_SMOOTH)");
448 /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
449 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP)))
450 state_blendop(context, state, STATE_RENDER(WINED3D_RS_BLENDOPALPHA));
452 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
454 GLenum srcBlendAlpha, dstBlendAlpha;
456 /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
457 if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
459 WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
460 return;
463 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
464 * source blending values which are still valid up to d3d9. They should
465 * not occur as dest blend values. */
466 d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA];
467 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
469 srcBlendAlpha = GL_SRC_ALPHA;
470 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
472 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
474 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
475 dstBlendAlpha = GL_SRC_ALPHA;
477 else
479 srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
480 dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
481 target->resource.format);
484 GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
485 checkGLcall("glBlendFuncSeparateEXT");
486 } else {
487 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
488 glBlendFunc(srcBlend, dstBlend);
489 checkGLcall("glBlendFunc");
492 /* Colorkey fixup for stage 0 alphaop depends on
493 * WINED3D_RS_ALPHABLENDENABLE state, so it may need updating. */
494 if (state->render_states[WINED3D_RS_COLORKEYENABLE])
495 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
498 static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
500 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
503 static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
505 const struct wined3d_gl_info *gl_info = context->gl_info;
506 float col[4];
508 TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
510 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
511 GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
512 checkGLcall("glBlendColor");
515 static void state_alpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
517 int glParm = 0;
518 float ref;
519 BOOL enable_ckey = FALSE;
521 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
523 /* Find out if the texture on the first stage has a ckey set
524 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
525 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
526 * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
527 * in case it finds some texture+colorkeyenable combination which needs extra care.
529 if (state->textures[0])
531 struct wined3d_surface *surface = surface_from_resource(state->textures[0]->sub_resources[0]);
533 if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
534 enable_ckey = TRUE;
537 if (enable_ckey || context->last_was_ckey)
538 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
539 context->last_was_ckey = enable_ckey;
541 if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
542 || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
544 glEnable(GL_ALPHA_TEST);
545 checkGLcall("glEnable GL_ALPHA_TEST");
546 } else {
547 glDisable(GL_ALPHA_TEST);
548 checkGLcall("glDisable GL_ALPHA_TEST");
549 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
550 * enable call
552 return;
555 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
557 glParm = GL_NOTEQUAL;
558 ref = 0.0f;
560 else
562 ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
563 glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
565 if(glParm) {
566 glAlphaFunc(glParm, ref);
567 checkGLcall("glAlphaFunc");
571 static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
573 const struct wined3d_device *device = context->swapchain->device;
575 /* Vertex and pixel shader states will call a shader upload, don't do
576 * anything as long one of them has an update pending. */
577 if (isStateDirty(context, STATE_VDECL)
578 || isStateDirty(context, STATE_PIXELSHADER))
579 return;
581 device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
584 static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
586 DWORD enable = 0xFFFFFFFF;
587 DWORD disable = 0x00000000;
589 if (use_vs(state))
591 const struct wined3d_device *device = context->swapchain->device;
593 if (!device->vs_clipping)
595 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
596 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
597 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
598 * of that - don't do anything here and keep them disabled
600 if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
602 static BOOL warned = FALSE;
603 if(!warned) {
604 FIXME("Clipping not supported with vertex shaders\n");
605 warned = TRUE;
608 return;
611 /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
612 * hardcoded into the shader. Update the shader to update the enabled clipplanes */
613 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
615 device->shader_backend->shader_select(context, use_ps(state), TRUE);
616 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
617 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
621 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
622 * of already set values
625 /* If enabling / disabling all
626 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
628 if (state->render_states[WINED3D_RS_CLIPPING])
630 enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
631 disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
633 else
635 disable = 0xffffffff;
636 enable = 0x00;
639 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
640 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
641 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
642 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
643 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
644 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
646 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
647 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
648 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
649 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
650 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
651 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
654 static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
656 const struct wined3d_gl_info *gl_info = context->gl_info;
657 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
658 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
659 * specular color. This is wrong:
660 * Separate specular color means the specular colour is maintained separately, whereas
661 * single color means it is merged in. However in both cases they are being used to
662 * some extent.
663 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
664 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
665 * running 1.4 yet!
668 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
669 * Instead, we need to setup the FinalCombiner properly.
671 * The default setup for the FinalCombiner is:
673 * <variable> <input> <mapping> <usage>
674 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
675 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
676 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
677 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
678 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
679 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
680 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
682 * That's pretty much fine as it is, except for variable B, which needs to take
683 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
684 * whether WINED3D_RS_SPECULARENABLE is enabled or not.
687 TRACE("Setting specular enable state and materials\n");
688 if (state->render_states[WINED3D_RS_SPECULARENABLE])
690 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
691 checkGLcall("glMaterialfv");
693 if (state->material.power > gl_info->limits.shininess)
695 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
696 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
697 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
698 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
699 * them, it should be safe to do so without major visual distortions.
701 WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
702 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
704 else
706 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
708 checkGLcall("glMaterialf(GL_SHININESS)");
710 if (gl_info->supported[EXT_SECONDARY_COLOR])
712 glEnable(GL_COLOR_SUM_EXT);
714 else
716 TRACE("Specular colors cannot be enabled in this version of opengl\n");
718 checkGLcall("glEnable(GL_COLOR_SUM)");
720 if (gl_info->supported[NV_REGISTER_COMBINERS])
722 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
723 checkGLcall("glFinalCombinerInputNV()");
725 } else {
726 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
728 /* for the case of enabled lighting: */
729 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
730 checkGLcall("glMaterialfv");
732 /* for the case of disabled lighting: */
733 if (gl_info->supported[EXT_SECONDARY_COLOR])
735 glDisable(GL_COLOR_SUM_EXT);
737 else
739 TRACE("Specular colors cannot be disabled in this version of opengl\n");
741 checkGLcall("glDisable(GL_COLOR_SUM)");
743 if (gl_info->supported[NV_REGISTER_COMBINERS])
745 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
746 checkGLcall("glFinalCombinerInputNV()");
750 TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
751 state->material.diffuse.r, state->material.diffuse.g,
752 state->material.diffuse.b, state->material.diffuse.a);
753 TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
754 state->material.ambient.r, state->material.ambient.g,
755 state->material.ambient.b, state->material.ambient.a);
756 TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
757 state->material.specular.r, state->material.specular.g,
758 state->material.specular.b, state->material.specular.a);
759 TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
760 state->material.emissive.r, state->material.emissive.g,
761 state->material.emissive.b, state->material.emissive.a);
763 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
764 checkGLcall("glMaterialfv(GL_AMBIENT)");
765 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
766 checkGLcall("glMaterialfv(GL_DIFFUSE)");
767 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
768 checkGLcall("glMaterialfv(GL_EMISSION)");
771 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
773 const struct wined3d_gl_info *gl_info = context->gl_info;
774 unsigned int i;
776 /* Note the texture color applies to all textures whereas
777 * GL_TEXTURE_ENV_COLOR applies to active only. */
778 float col[4];
779 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
781 /* And now the default texture color as well */
782 for (i = 0; i < gl_info->limits.texture_stages; ++i)
784 /* Note the WINED3D_RS value applies to all textures, but GL has one
785 * per texture, so apply it now ready to be used! */
786 context_active_texture(context, gl_info, i);
788 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
789 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
793 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
794 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
796 const struct wined3d_gl_info *gl_info = context->gl_info;
798 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
799 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
800 GL_EXTCALL(glActiveStencilFaceEXT(face));
801 checkGLcall("glActiveStencilFaceEXT(...)");
802 glStencilFunc(func, ref, mask);
803 checkGLcall("glStencilFunc(...)");
804 glStencilOp(stencilFail, depthFail, stencilPass);
805 checkGLcall("glStencilOp(...)");
808 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
810 switch (op)
812 case WINED3D_STENCIL_OP_KEEP:
813 return GL_KEEP;
814 case WINED3D_STENCIL_OP_ZERO:
815 return GL_ZERO;
816 case WINED3D_STENCIL_OP_REPLACE:
817 return GL_REPLACE;
818 case WINED3D_STENCIL_OP_INCR_SAT:
819 return GL_INCR;
820 case WINED3D_STENCIL_OP_DECR_SAT:
821 return GL_DECR;
822 case WINED3D_STENCIL_OP_INVERT:
823 return GL_INVERT;
824 case WINED3D_STENCIL_OP_INCR:
825 return GL_INCR_WRAP_EXT;
826 case WINED3D_STENCIL_OP_DECR:
827 return GL_DECR_WRAP_EXT;
828 default:
829 FIXME("Unrecognized stencil op %#x.\n", op);
830 return GL_KEEP;
834 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
836 const struct wined3d_gl_info *gl_info = context->gl_info;
837 DWORD onesided_enable = FALSE;
838 DWORD twosided_enable = FALSE;
839 GLint func = GL_ALWAYS;
840 GLint func_ccw = GL_ALWAYS;
841 GLint ref = 0;
842 GLuint mask = 0;
843 GLint stencilFail = GL_KEEP;
844 GLint depthFail = GL_KEEP;
845 GLint stencilPass = GL_KEEP;
846 GLint stencilFail_ccw = GL_KEEP;
847 GLint depthFail_ccw = GL_KEEP;
848 GLint stencilPass_ccw = GL_KEEP;
850 /* No stencil test without a stencil buffer. */
851 if (!state->fb->depth_stencil)
853 glDisable(GL_STENCIL_TEST);
854 checkGLcall("glDisable GL_STENCIL_TEST");
855 return;
858 onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
859 twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
860 if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
861 func = GL_ALWAYS;
862 if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
863 func_ccw = GL_ALWAYS;
864 ref = state->render_states[WINED3D_RS_STENCILREF];
865 mask = state->render_states[WINED3D_RS_STENCILMASK];
866 stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
867 depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
868 stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
869 stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
870 depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
871 stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
873 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
874 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
875 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
876 onesided_enable, twosided_enable, ref, mask,
877 func, stencilFail, depthFail, stencilPass,
878 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
880 if (twosided_enable && onesided_enable) {
881 glEnable(GL_STENCIL_TEST);
882 checkGLcall("glEnable GL_STENCIL_TEST");
884 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
886 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
887 * which has an effect on the code below too. If we apply the front face
888 * afterwards, we are sure that the active stencil face is set to front,
889 * and other stencil functions which do not use two sided stencil do not have
890 * to set it back
892 renderstate_stencil_twosided(context, GL_BACK,
893 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
894 renderstate_stencil_twosided(context, GL_FRONT,
895 func, ref, mask, stencilFail, depthFail, stencilPass);
897 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
899 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
900 checkGLcall("glStencilFuncSeparateATI(...)");
901 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
902 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
903 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
904 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
905 } else {
906 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
909 else if(onesided_enable)
911 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
913 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
914 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
917 /* This code disables the ATI extension as well, since the standard stencil functions are equal
918 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
920 glEnable(GL_STENCIL_TEST);
921 checkGLcall("glEnable GL_STENCIL_TEST");
922 glStencilFunc(func, ref, mask);
923 checkGLcall("glStencilFunc(...)");
924 glStencilOp(stencilFail, depthFail, stencilPass);
925 checkGLcall("glStencilOp(...)");
926 } else {
927 glDisable(GL_STENCIL_TEST);
928 checkGLcall("glDisable GL_STENCIL_TEST");
932 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
934 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
935 const struct wined3d_gl_info *gl_info = context->gl_info;
937 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
938 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
939 glStencilMask(mask);
940 checkGLcall("glStencilMask");
941 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
942 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
943 glStencilMask(mask);
946 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
948 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
950 glStencilMask(mask);
951 checkGLcall("glStencilMask");
954 static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
957 const struct wined3d_gl_info *gl_info = context->gl_info;
958 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
960 if (!state->render_states[WINED3D_RS_FOGENABLE])
961 return;
963 /* Table fog on: Never use fog coords, and use per-fragment fog */
964 if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
966 glHint(GL_FOG_HINT, GL_NICEST);
967 if(context->fog_coord) {
968 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
969 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
970 context->fog_coord = FALSE;
973 /* Range fog is only used with per-vertex fog in d3d */
974 if (gl_info->supported[NV_FOG_DISTANCE])
976 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
977 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
979 return;
982 /* Otherwise use per-vertex fog in any case */
983 glHint(GL_FOG_HINT, GL_FASTEST);
985 if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
987 /* No fog at all, or transformed vertices: Use fog coord */
988 if(!context->fog_coord) {
989 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
990 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
991 context->fog_coord = TRUE;
994 else
996 /* Otherwise, use the fragment depth */
997 if(context->fog_coord) {
998 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
999 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1000 context->fog_coord = FALSE;
1003 if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
1005 if (gl_info->supported[NV_FOG_DISTANCE])
1007 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1008 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1010 else
1012 WARN("Range fog enabled, but not supported by this GL implementation.\n");
1015 else if (gl_info->supported[NV_FOG_DISTANCE])
1017 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1018 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1023 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1025 float fogstart, fogend;
1026 union {
1027 DWORD d;
1028 float f;
1029 } tmpvalue;
1031 switch(context->fog_source) {
1032 case FOGSOURCE_VS:
1033 fogstart = 1.0f;
1034 fogend = 0.0f;
1035 break;
1037 case FOGSOURCE_COORD:
1038 fogstart = 255.0f;
1039 fogend = 0.0f;
1040 break;
1042 case FOGSOURCE_FFP:
1043 tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
1044 fogstart = tmpvalue.f;
1045 tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
1046 fogend = tmpvalue.f;
1047 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
1048 if(fogstart == fogend) {
1049 fogstart = -1.0f / 0.0f;
1050 fogend = 0.0f;
1052 break;
1054 default:
1055 /* This should not happen.context->fog_source is set in wined3d, not the app.
1056 * Still this is needed to make the compiler happy
1058 ERR("Unexpected fog coordinate source\n");
1059 fogstart = 0.0f;
1060 fogend = 0.0f;
1063 glFogf(GL_FOG_START, fogstart);
1064 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1065 TRACE("Fog Start == %f\n", fogstart);
1067 glFogf(GL_FOG_END, fogend);
1068 checkGLcall("glFogf(GL_FOG_END, fogend)");
1069 TRACE("Fog End == %f\n", fogend);
1072 void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1074 enum fogsource new_source;
1076 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
1078 if (!state->render_states[WINED3D_RS_FOGENABLE])
1080 /* No fog? Disable it, and we're done :-) */
1081 glDisableWINE(GL_FOG);
1082 checkGLcall("glDisable GL_FOG");
1083 return;
1086 /* Fog Rules:
1088 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1089 * It can use the Z value of the vertex, or the alpha component of the specular color.
1090 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1091 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1092 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1094 * FOGTABLEMODE != NONE:
1095 * The Z value is used, with the equation specified, no matter what vertex type.
1097 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1098 * Per vertex fog is calculated using the specified fog equation and the parameters
1100 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1101 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1102 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1105 * Rules for vertex fog with shaders:
1107 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1108 * the fog computation to happen during transformation while openGL expects it to happen
1109 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1110 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1111 * To solve this problem, WineD3D does:
1112 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1113 * shader,
1114 * and 2) disables the fog computation (in either the fixed function or programmable
1115 * rasterizer) if using a vertex program.
1117 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1118 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1119 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1120 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1121 * There are some GL differences between specular fog coords and vertex shaders though.
1123 * With table fog the vertex shader fog coordinate is ignored.
1125 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1126 * without shaders).
1129 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1130 * the system will apply only pixel(=table) fog effects."
1132 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
1134 if (use_vs(state))
1136 glFogi(GL_FOG_MODE, GL_LINEAR);
1137 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1138 new_source = FOGSOURCE_VS;
1140 else
1142 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
1144 /* If processed vertices are used, fall through to the NONE case */
1145 case WINED3D_FOG_EXP:
1146 if (!context->last_was_rhw)
1148 glFogi(GL_FOG_MODE, GL_EXP);
1149 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1150 new_source = FOGSOURCE_FFP;
1151 break;
1153 /* drop through */
1155 case WINED3D_FOG_EXP2:
1156 if (!context->last_was_rhw)
1158 glFogi(GL_FOG_MODE, GL_EXP2);
1159 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1160 new_source = FOGSOURCE_FFP;
1161 break;
1163 /* drop through */
1165 case WINED3D_FOG_LINEAR:
1166 if (!context->last_was_rhw)
1168 glFogi(GL_FOG_MODE, GL_LINEAR);
1169 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1170 new_source = FOGSOURCE_FFP;
1171 break;
1173 /* drop through */
1175 case WINED3D_FOG_NONE:
1176 /* Both are none? According to msdn the alpha channel of the specular
1177 * color contains a fog factor. Set it in drawStridedSlow.
1178 * Same happens with Vertexfog on transformed vertices
1180 new_source = FOGSOURCE_COORD;
1181 glFogi(GL_FOG_MODE, GL_LINEAR);
1182 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1183 break;
1185 default:
1186 FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
1187 state->render_states[WINED3D_RS_FOGVERTEXMODE]);
1188 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1191 } else {
1192 new_source = FOGSOURCE_FFP;
1194 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
1196 case WINED3D_FOG_EXP:
1197 glFogi(GL_FOG_MODE, GL_EXP);
1198 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1199 break;
1201 case WINED3D_FOG_EXP2:
1202 glFogi(GL_FOG_MODE, GL_EXP2);
1203 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1204 break;
1206 case WINED3D_FOG_LINEAR:
1207 glFogi(GL_FOG_MODE, GL_LINEAR);
1208 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1209 break;
1211 case WINED3D_FOG_NONE: /* Won't happen */
1212 default:
1213 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
1214 state->render_states[WINED3D_RS_FOGTABLEMODE]);
1218 glEnableWINE(GL_FOG);
1219 checkGLcall("glEnable GL_FOG");
1220 if (new_source != context->fog_source)
1222 context->fog_source = new_source;
1223 state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
1227 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1229 float col[4];
1231 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
1232 glFogfv(GL_FOG_COLOR, &col[0]);
1233 checkGLcall("glFog GL_FOG_COLOR");
1236 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1238 union {
1239 DWORD d;
1240 float f;
1241 } tmpvalue;
1243 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1244 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1245 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1248 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1250 const struct wined3d_device *device = context->swapchain->device;
1251 GLenum Parm = 0;
1253 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1254 * The vertex declaration will call this function if the fixed function pipeline is used.
1257 if(isStateDirty(context, STATE_VDECL)) {
1258 return;
1261 context->num_untracked_materials = 0;
1262 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1263 && state->render_states[WINED3D_RS_COLORVERTEX])
1265 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1266 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
1267 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
1268 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
1269 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
1271 if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1273 if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1274 Parm = GL_AMBIENT_AND_DIFFUSE;
1275 else
1276 Parm = GL_DIFFUSE;
1277 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1279 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1280 context->num_untracked_materials++;
1282 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1284 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1285 context->num_untracked_materials++;
1288 else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1290 Parm = GL_AMBIENT;
1291 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1293 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1294 context->num_untracked_materials++;
1296 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1298 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1299 context->num_untracked_materials++;
1302 else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1304 Parm = GL_EMISSION;
1305 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1307 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1308 context->num_untracked_materials++;
1311 else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1313 Parm = GL_SPECULAR;
1317 /* Nothing changed, return. */
1318 if (Parm == context->tracking_parm) return;
1320 if(!Parm) {
1321 glDisable(GL_COLOR_MATERIAL);
1322 checkGLcall("glDisable GL_COLOR_MATERIAL");
1323 } else {
1324 glColorMaterial(GL_FRONT_AND_BACK, Parm);
1325 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1326 glEnable(GL_COLOR_MATERIAL);
1327 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1330 /* Apparently calls to glMaterialfv are ignored for properties we're
1331 * tracking with glColorMaterial, so apply those here. */
1332 switch (context->tracking_parm) {
1333 case GL_AMBIENT_AND_DIFFUSE:
1334 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1335 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1336 checkGLcall("glMaterialfv");
1337 break;
1339 case GL_DIFFUSE:
1340 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1341 checkGLcall("glMaterialfv");
1342 break;
1344 case GL_AMBIENT:
1345 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1346 checkGLcall("glMaterialfv");
1347 break;
1349 case GL_EMISSION:
1350 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
1351 checkGLcall("glMaterialfv");
1352 break;
1354 case GL_SPECULAR:
1355 /* Only change material color if specular is enabled, otherwise it is set to black */
1356 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1358 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
1359 checkGLcall("glMaterialfv");
1361 else
1363 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1364 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1365 checkGLcall("glMaterialfv");
1367 break;
1370 context->tracking_parm = Parm;
1373 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1375 union
1377 DWORD d;
1378 struct wined3d_line_pattern lp;
1379 } tmppattern;
1380 tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
1382 TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1384 if (tmppattern.lp.repeat_factor)
1386 glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1387 checkGLcall("glLineStipple(repeat, linepattern)");
1388 glEnable(GL_LINE_STIPPLE);
1389 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1391 else
1393 glDisable(GL_LINE_STIPPLE);
1394 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1398 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1400 if (isStateDirty(context, STATE_VDECL))
1401 return;
1403 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1404 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1405 * by zero and is not properly defined in opengl, so avoid it
1407 if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
1408 && (context->swapchain->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1410 glEnable(GL_NORMALIZE);
1411 checkGLcall("glEnable(GL_NORMALIZE);");
1413 else
1415 glDisable(GL_NORMALIZE);
1416 checkGLcall("glDisable(GL_NORMALIZE);");
1420 static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1422 union {
1423 DWORD d;
1424 float f;
1425 } tmpvalue;
1427 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1428 if (tmpvalue.f != 1.0f)
1430 FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1432 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1433 if (tmpvalue.f != 64.0f)
1435 FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1440 static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1442 const struct wined3d_gl_info *gl_info = context->gl_info;
1443 union
1445 DWORD d;
1446 float f;
1447 } min, max;
1449 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1450 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1452 /* Max point size trumps min point size */
1453 if(min.f > max.f) {
1454 min.f = max.f;
1457 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1458 checkGLcall("glPointParameterfEXT(...)");
1459 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1460 checkGLcall("glPointParameterfEXT(...)");
1463 static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1465 const struct wined3d_gl_info *gl_info = context->gl_info;
1466 union
1468 DWORD d;
1469 float f;
1470 } min, max;
1472 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1473 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1475 /* Max point size trumps min point size */
1476 if(min.f > max.f) {
1477 min.f = max.f;
1480 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1481 checkGLcall("glPointParameterfARB(...)");
1482 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1483 checkGLcall("glPointParameterfARB(...)");
1486 static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1488 const struct wined3d_gl_info *gl_info = context->gl_info;
1489 /* TODO: Group this with the viewport */
1491 * POINTSCALEENABLE controls how point size value is treated. If set to
1492 * true, the point size is scaled with respect to height of viewport.
1493 * When set to false point size is in pixels.
1496 /* Default values */
1497 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1498 union {
1499 DWORD d;
1500 float f;
1501 } pointSize, A, B, C;
1503 pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
1504 A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
1505 B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
1506 C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
1508 if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1510 DWORD h = state->viewport.height;
1511 GLfloat scaleFactor;
1513 if (pointSize.f < gl_info->limits.pointsize_min)
1515 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1516 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1517 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1518 * are less than 1.0f. scale_factor = 1.0f / point_size.
1520 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1521 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1522 * is 1.0, but then accepts points below that and draws too small points
1524 pointSize.f = gl_info->limits.pointsize_min;
1526 else if(pointSize.f > gl_info->limits.pointsize_max)
1528 /* gl already scales the input to glPointSize,
1529 * d3d scales the result after the point size scale.
1530 * If the point size is bigger than the max size, use the
1531 * scaling to scale it bigger, and set the gl point size to max
1533 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1534 TRACE("scale: %f\n", scaleFactor);
1535 pointSize.f = gl_info->limits.pointsize_max;
1536 } else {
1537 scaleFactor = 1.0f;
1539 scaleFactor = powf(h * scaleFactor, 2);
1541 att[0] = A.f / scaleFactor;
1542 att[1] = B.f / scaleFactor;
1543 att[2] = C.f / scaleFactor;
1546 if (gl_info->supported[ARB_POINT_PARAMETERS])
1548 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1549 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1551 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1553 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1554 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1556 else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1558 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1561 glPointSize(pointSize.f);
1562 checkGLcall("glPointSize(...);");
1565 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1567 WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
1570 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1572 DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
1573 DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
1574 DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
1575 DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
1577 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1578 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1579 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1580 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1581 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1582 glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1583 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1584 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1585 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1586 checkGLcall("glColorMask(...)");
1588 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1589 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1591 FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1592 mask0, mask1, mask2, mask3);
1593 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1597 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1599 GL_EXTCALL(glColorMaskIndexedEXT(index,
1600 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1601 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1602 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1603 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1606 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1608 set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
1611 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1613 set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
1616 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1618 set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
1621 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1623 set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
1626 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1628 if (state->render_states[WINED3D_RS_LOCALVIEWER])
1630 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1631 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1632 } else {
1633 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1634 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1638 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1640 if (state->render_states[WINED3D_RS_LASTPIXEL])
1642 TRACE("Last Pixel Drawing Enabled\n");
1644 else
1646 static BOOL warned;
1647 if (!warned) {
1648 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1649 warned = TRUE;
1650 } else {
1651 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1656 static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1658 static BOOL warned;
1660 /* TODO: NV_POINT_SPRITE */
1661 if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1663 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1664 FIXME("Point sprites not supported\n");
1665 warned = TRUE;
1669 static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1671 if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1673 glEnable(GL_POINT_SPRITE_ARB);
1674 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1675 } else {
1676 glDisable(GL_POINT_SPRITE_ARB);
1677 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1681 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1683 if (state->render_states[WINED3D_RS_WRAP0]
1684 || state->render_states[WINED3D_RS_WRAP1]
1685 || state->render_states[WINED3D_RS_WRAP2]
1686 || state->render_states[WINED3D_RS_WRAP3]
1687 || state->render_states[WINED3D_RS_WRAP4]
1688 || state->render_states[WINED3D_RS_WRAP5]
1689 || state->render_states[WINED3D_RS_WRAP6]
1690 || state->render_states[WINED3D_RS_WRAP7]
1691 || state->render_states[WINED3D_RS_WRAP8]
1692 || state->render_states[WINED3D_RS_WRAP9]
1693 || state->render_states[WINED3D_RS_WRAP10]
1694 || state->render_states[WINED3D_RS_WRAP11]
1695 || state->render_states[WINED3D_RS_WRAP12]
1696 || state->render_states[WINED3D_RS_WRAP13]
1697 || state->render_states[WINED3D_RS_WRAP14]
1698 || state->render_states[WINED3D_RS_WRAP15])
1699 FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
1702 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1704 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1705 WARN("Multisample antialiasing not supported by GL.\n");
1708 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1710 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1712 glEnable(GL_MULTISAMPLE_ARB);
1713 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1714 } else {
1715 glDisable(GL_MULTISAMPLE_ARB);
1716 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1720 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1722 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
1724 glEnable(GL_SCISSOR_TEST);
1725 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1726 } else {
1727 glDisable(GL_SCISSOR_TEST);
1728 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1732 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1733 * OpenGL the bias is specified in units of "the smallest value that is
1734 * guaranteed to produce a resolvable offset for a given implementation". To
1735 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1736 * There's no practical way to retrieve that value from a given GL
1737 * implementation, but the D3D application has essentially the same problem,
1738 * which makes a guess of the depth buffer format's highest possible value a
1739 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1740 * depth slope, and doesn't need to be scaled. */
1741 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1743 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
1744 || state->render_states[WINED3D_RS_DEPTHBIAS])
1746 const struct wined3d_surface *depth = state->fb->depth_stencil;
1747 float scale;
1749 union
1751 DWORD d;
1752 float f;
1753 } scale_bias, const_bias;
1755 scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
1756 const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
1758 glEnable(GL_POLYGON_OFFSET_FILL);
1759 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1761 if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
1763 float bias = -(float)const_bias.d;
1764 glPolygonOffset(bias, bias);
1765 checkGLcall("glPolygonOffset");
1767 else
1769 if (depth)
1771 const struct wined3d_format *fmt = depth->resource.format;
1772 scale = powf(2, fmt->depth_size) - 1;
1773 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
1774 debug_d3dformat(fmt->id), scale);
1776 else
1778 /* The context manager will reapply this state on a depth stencil change */
1779 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
1780 scale = 0.0f;
1783 glPolygonOffset(scale_bias.f, const_bias.f * scale);
1784 checkGLcall("glPolygonOffset(...)");
1787 else
1789 glDisable(GL_POLYGON_OFFSET_FILL);
1790 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1794 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1796 if (state->render_states[WINED3D_RS_ZVISIBLE])
1797 FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
1800 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1802 if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
1804 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1805 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1806 } else {
1807 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1808 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1812 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1814 if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
1815 FIXME("Stippled Alpha not supported yet.\n");
1818 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1820 if (state->render_states[WINED3D_RS_ANTIALIAS])
1821 FIXME("Antialias not supported yet.\n");
1824 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1826 if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
1827 FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
1828 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
1831 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1833 if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
1834 FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
1835 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
1838 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1840 union {
1841 DWORD d;
1842 float f;
1843 } tmpvalue;
1844 tmpvalue.f = 1.0f;
1846 if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
1848 static BOOL displayed = FALSE;
1850 tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
1851 if(!displayed)
1852 FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1854 displayed = TRUE;
1858 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1860 if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
1861 FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
1862 state->render_states[WINED3D_RS_POSITIONDEGREE]);
1865 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1867 if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
1868 FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
1869 state->render_states[WINED3D_RS_NORMALDEGREE]);
1872 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1874 if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
1875 FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1876 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
1879 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1881 union {
1882 DWORD d;
1883 float f;
1884 } zmin, zmax;
1886 const struct wined3d_gl_info *gl_info = context->gl_info;
1888 if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1890 zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
1891 zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
1893 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1894 * In d3d9 test is not performed in this case*/
1895 if (zmin.f <= zmax.f)
1897 glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1898 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1899 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1900 checkGLcall("glDepthBoundsEXT(...)");
1902 else {
1903 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1904 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1907 else {
1908 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1909 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1912 state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
1915 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1917 if (state->render_states[WINED3D_RS_WRAPU])
1918 FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
1921 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1923 if (state->render_states[WINED3D_RS_WRAPV])
1924 FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
1927 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1929 if (state->render_states[WINED3D_RS_MONOENABLE])
1930 FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
1933 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1935 if (state->render_states[WINED3D_RS_ROP2])
1936 FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
1939 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1941 if (state->render_states[WINED3D_RS_PLANEMASK])
1942 FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
1945 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1947 if (state->render_states[WINED3D_RS_SUBPIXEL])
1948 FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
1951 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1953 if (state->render_states[WINED3D_RS_SUBPIXELX])
1954 FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
1957 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1959 if (state->render_states[WINED3D_RS_STIPPLEENABLE])
1960 FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
1963 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1965 if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
1966 FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
1969 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1971 if (state->render_states[WINED3D_RS_ANISOTROPY])
1972 FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
1975 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1977 if (state->render_states[WINED3D_RS_FLUSHBATCH])
1978 FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
1981 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1983 if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
1984 FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
1987 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1989 if (state->render_states[WINED3D_RS_EXTENTS])
1990 FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
1993 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1995 if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
1996 FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
1999 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2001 if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
2002 FIXME("Software vertex processing not implemented.\n");
2005 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2006 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2007 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2008 * flag specifies the complement of the input should be used. */
2009 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2010 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2012 /* Calculate the operand */
2013 if (complement) {
2014 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2015 else *operand = GL_ONE_MINUS_SRC_COLOR;
2016 } else {
2017 if (from_alpha) *operand = GL_SRC_ALPHA;
2018 else *operand = GL_SRC_COLOR;
2021 /* Calculate the source */
2022 switch (arg & WINED3DTA_SELECTMASK) {
2023 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2024 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2025 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2026 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2027 case WINED3DTA_SPECULAR:
2029 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2030 * 'Secondary color' and isn't supported until base GL supports it
2031 * There is no concept of temp registers as far as I can tell
2033 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2034 *source = GL_TEXTURE;
2035 break;
2036 default:
2037 FIXME("Unrecognized texture arg %#x\n", arg);
2038 *source = GL_TEXTURE;
2039 break;
2043 /* Setup the texture operations texture stage states */
2044 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2045 BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2047 GLenum src1, src2, src3;
2048 GLenum opr1, opr2, opr3;
2049 GLenum comb_target;
2050 GLenum src0_target, src1_target, src2_target;
2051 GLenum opr0_target, opr1_target, opr2_target;
2052 GLenum scal_target;
2053 GLenum opr=0, invopr, src3_target, opr3_target;
2054 BOOL Handled = FALSE;
2056 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2058 /* This is called by a state handler which has the gl lock held and a context for the thread */
2060 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2061 the form (a1 <operation> a2). However, some of the more complex operations
2062 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2063 in a third parameter called a0. Therefore these are operations of the form
2064 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2066 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2067 functions below, expect their syntax to differ slightly to those listed in the
2068 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2069 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2071 if (isAlpha)
2073 comb_target = GL_COMBINE_ALPHA;
2074 src0_target = GL_SOURCE0_ALPHA;
2075 src1_target = GL_SOURCE1_ALPHA;
2076 src2_target = GL_SOURCE2_ALPHA;
2077 opr0_target = GL_OPERAND0_ALPHA;
2078 opr1_target = GL_OPERAND1_ALPHA;
2079 opr2_target = GL_OPERAND2_ALPHA;
2080 scal_target = GL_ALPHA_SCALE;
2082 else
2084 comb_target = GL_COMBINE_RGB;
2085 src0_target = GL_SOURCE0_RGB;
2086 src1_target = GL_SOURCE1_RGB;
2087 src2_target = GL_SOURCE2_RGB;
2088 opr0_target = GL_OPERAND0_RGB;
2089 opr1_target = GL_OPERAND1_RGB;
2090 opr2_target = GL_OPERAND2_RGB;
2091 scal_target = GL_RGB_SCALE;
2094 /* If a texture stage references an invalid texture unit the stage just
2095 * passes through the result from the previous stage */
2096 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2098 arg1 = WINED3DTA_CURRENT;
2099 op = WINED3D_TOP_SELECT_ARG1;
2102 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2104 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2105 } else {
2106 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2108 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2109 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2111 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2113 Handled = TRUE; /* Assume will be handled */
2115 /* Other texture operations require special extensions: */
2116 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2118 if (isAlpha) {
2119 opr = GL_SRC_ALPHA;
2120 invopr = GL_ONE_MINUS_SRC_ALPHA;
2121 src3_target = GL_SOURCE3_ALPHA_NV;
2122 opr3_target = GL_OPERAND3_ALPHA_NV;
2123 } else {
2124 opr = GL_SRC_COLOR;
2125 invopr = GL_ONE_MINUS_SRC_COLOR;
2126 src3_target = GL_SOURCE3_RGB_NV;
2127 opr3_target = GL_OPERAND3_RGB_NV;
2129 switch (op)
2131 case WINED3D_TOP_DISABLE: /* Only for alpha */
2132 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2133 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2134 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2135 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2136 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2137 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2138 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2139 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2140 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2141 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2142 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2143 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2144 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2145 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2146 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2147 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2148 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2149 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2150 break;
2151 case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
2152 case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
2153 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2154 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2155 if (op == WINED3D_TOP_SELECT_ARG1)
2157 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2158 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2159 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2160 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2161 } else {
2162 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2163 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2164 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2165 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2167 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2168 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2169 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2170 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2171 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2172 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2173 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2174 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2175 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2176 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2177 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2178 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2179 break;
2181 case WINED3D_TOP_MODULATE:
2182 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2183 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2184 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2185 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2186 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2187 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2188 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2189 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2190 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2191 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2192 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2193 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2194 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2195 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2196 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2197 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2198 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2199 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2200 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2201 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2202 break;
2203 case WINED3D_TOP_MODULATE_2X:
2204 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2205 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2206 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2207 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2208 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2209 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2210 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2211 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2212 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2213 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2214 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2215 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2216 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2217 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2218 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2219 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2220 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2221 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2222 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2223 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2224 break;
2225 case WINED3D_TOP_MODULATE_4X:
2226 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2227 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2228 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2229 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2230 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2231 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2232 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2233 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2234 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2235 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2236 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2237 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2238 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2239 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2240 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2241 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2242 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2243 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2244 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2245 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2246 break;
2248 case WINED3D_TOP_ADD:
2249 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2250 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2251 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2252 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2253 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2254 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2255 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2256 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2257 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2258 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2259 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2260 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2261 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2262 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2263 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2264 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2265 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2266 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2267 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2268 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2269 break;
2271 case WINED3D_TOP_ADD_SIGNED:
2272 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2273 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2274 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2275 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2276 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2277 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2278 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2279 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2280 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2281 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2282 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2283 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2284 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2285 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2286 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2287 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2288 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2289 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2290 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2291 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2292 break;
2294 case WINED3D_TOP_ADD_SIGNED_2X:
2295 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2296 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2297 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2298 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2299 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2300 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2301 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2302 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2303 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2304 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2305 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2306 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2307 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2308 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2309 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2310 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2311 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2312 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2313 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2314 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2315 break;
2317 case WINED3D_TOP_ADD_SMOOTH:
2318 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2319 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2320 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2321 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2322 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2323 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2324 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2325 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2326 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2327 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2328 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2329 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2330 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2331 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2332 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2333 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2334 switch (opr1) {
2335 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2336 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2337 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2338 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2340 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2341 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2342 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2343 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2344 break;
2346 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2347 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2348 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2349 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2350 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2351 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2352 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2353 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
2354 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
2355 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2356 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2357 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2358 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2359 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2360 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2361 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
2362 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
2363 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2364 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2365 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2366 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2367 break;
2368 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2369 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2370 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2371 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2372 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2373 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2374 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2375 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2376 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2377 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2378 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2379 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2380 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2381 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2382 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2383 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2384 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2385 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2386 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2387 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2388 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2389 break;
2390 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2391 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2392 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2393 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2394 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2395 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2396 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2397 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
2398 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
2399 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2400 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2401 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2402 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2403 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2404 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2405 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
2406 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
2407 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2408 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2409 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2410 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2411 break;
2412 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2413 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2414 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2415 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2416 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2417 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2418 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2419 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2420 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2421 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2422 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2423 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2424 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2425 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2426 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2427 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2428 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2429 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2430 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2431 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2432 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2433 break;
2434 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2435 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2436 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2437 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2438 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2439 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2440 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2441 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2442 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2443 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2444 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2445 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2446 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2447 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2448 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2449 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2450 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2451 switch (opr) {
2452 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2453 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2455 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2456 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2457 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2458 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2459 break;
2460 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2461 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2462 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2463 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2464 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2465 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2466 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2467 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2468 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2469 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2470 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2471 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2472 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2473 switch (opr1) {
2474 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2475 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2477 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2478 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2479 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2480 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2481 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2482 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2483 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2484 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2485 break;
2486 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2487 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2488 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2489 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2490 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2491 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2492 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2493 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2494 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2495 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2496 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2497 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2498 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2499 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2500 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2501 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2502 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2503 switch (opr1) {
2504 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2505 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2506 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2507 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2509 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2510 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2511 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2512 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2513 break;
2514 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2515 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2516 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2517 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2518 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2519 switch (opr1) {
2520 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2521 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2522 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2523 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2525 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2526 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2527 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2528 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2529 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2530 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2531 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2532 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2533 switch (opr1) {
2534 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2535 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2537 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2538 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2539 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2540 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2541 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2542 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2543 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2544 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2545 break;
2546 case WINED3D_TOP_MULTIPLY_ADD:
2547 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2548 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2549 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2550 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2551 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2552 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2553 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2554 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2555 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2556 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2557 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2558 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2559 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2560 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2561 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2562 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2563 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2564 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2565 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2566 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2567 break;
2569 case WINED3D_TOP_BUMPENVMAP:
2570 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
2571 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2573 default:
2574 Handled = FALSE;
2576 if (Handled) {
2577 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2578 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2580 return;
2582 } /* GL_NV_texture_env_combine4 */
2584 Handled = TRUE; /* Again, assume handled */
2585 switch (op) {
2586 case WINED3D_TOP_DISABLE: /* Only for alpha */
2587 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2588 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2589 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2590 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2591 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2592 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2593 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2594 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2595 break;
2596 case WINED3D_TOP_SELECT_ARG1:
2597 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2598 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2599 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2600 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2601 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2602 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2603 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2604 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2605 break;
2606 case WINED3D_TOP_SELECT_ARG2:
2607 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2608 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2609 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2610 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2611 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2612 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2613 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2614 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2615 break;
2616 case WINED3D_TOP_MODULATE:
2617 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2618 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2619 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2620 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2621 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2622 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2623 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2624 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2625 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2626 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2627 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2628 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2629 break;
2630 case WINED3D_TOP_MODULATE_2X:
2631 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2632 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2633 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2634 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2635 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2636 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2637 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2638 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2639 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2640 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2641 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2642 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2643 break;
2644 case WINED3D_TOP_MODULATE_4X:
2645 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2646 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2647 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2648 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2649 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2650 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2651 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2652 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2653 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2654 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2655 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2656 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2657 break;
2658 case WINED3D_TOP_ADD:
2659 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2660 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2661 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2662 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2663 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2664 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2665 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2666 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2667 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2668 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2669 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2670 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2671 break;
2672 case WINED3D_TOP_ADD_SIGNED:
2673 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2674 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2675 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2676 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2677 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2678 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2679 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2680 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2681 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2682 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2683 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2684 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2685 break;
2686 case WINED3D_TOP_ADD_SIGNED_2X:
2687 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2688 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2689 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2690 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2691 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2692 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2693 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2694 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2695 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2696 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2697 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2698 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2699 break;
2700 case WINED3D_TOP_SUBTRACT:
2701 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2703 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2704 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2705 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2706 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2707 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2708 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2709 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2710 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2711 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2712 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2713 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2714 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2715 } else {
2716 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2718 break;
2720 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2721 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2722 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2723 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2724 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2725 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2726 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2727 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2728 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2729 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2730 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2731 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
2732 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2733 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2734 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2735 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2736 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2737 break;
2738 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2739 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2740 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2741 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2742 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2743 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2744 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2745 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2746 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2747 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2748 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2749 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2750 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2751 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2752 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2753 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2754 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2755 break;
2756 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2757 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2758 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2759 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2760 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2761 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2762 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2763 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2764 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2765 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2766 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2767 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
2768 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2769 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2770 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2771 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2772 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2773 break;
2774 case WINED3D_TOP_BLEND_CURRENT_ALPHA:
2775 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2776 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2777 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2778 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2779 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2780 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2781 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2782 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2783 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2784 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2785 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
2786 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2787 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2788 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2789 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2790 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2791 break;
2792 case WINED3D_TOP_DOTPRODUCT3:
2793 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2795 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2796 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2798 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2800 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2801 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2802 } else {
2803 FIXME("This version of opengl does not support GL_DOT3\n");
2805 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2806 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2807 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2808 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2809 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2810 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2811 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2812 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2813 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2814 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2815 break;
2816 case WINED3D_TOP_LERP:
2817 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2818 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2819 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2820 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2821 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2822 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2823 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2824 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2825 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2826 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2827 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2828 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2829 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2830 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2831 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2832 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2833 break;
2834 case WINED3D_TOP_ADD_SMOOTH:
2835 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2837 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2838 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2839 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2840 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2841 switch (opr1) {
2842 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2843 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2844 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2845 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2847 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2848 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2849 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2850 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2851 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2852 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2853 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2854 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2855 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2856 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2857 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2858 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2859 } else
2860 Handled = FALSE;
2861 break;
2862 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2863 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2865 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2866 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2867 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2868 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2869 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2870 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2871 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2872 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2873 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2874 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2875 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2876 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2877 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2878 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2879 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2880 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2881 } else
2882 Handled = FALSE;
2883 break;
2884 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2885 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2887 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2888 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2889 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2890 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2891 switch (opr1) {
2892 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2893 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2894 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2895 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2897 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2898 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2899 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2900 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2901 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2902 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2903 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2904 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2905 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2906 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2907 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2908 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2909 } else
2910 Handled = FALSE;
2911 break;
2912 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2913 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2915 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2916 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2917 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2918 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2919 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2920 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2921 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2922 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2923 switch (opr1) {
2924 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2925 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2926 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2927 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2929 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2930 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2931 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2932 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2933 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2934 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2935 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2936 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2937 } else
2938 Handled = FALSE;
2939 break;
2940 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2941 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2943 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2944 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2945 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2946 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2947 switch (opr1) {
2948 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2949 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2950 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2951 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2953 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2954 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2955 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2956 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2957 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2958 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2959 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2960 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2961 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2962 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2963 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2964 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2965 } else
2966 Handled = FALSE;
2967 break;
2968 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2969 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2971 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2972 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2973 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2974 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2975 switch (opr1) {
2976 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2977 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2978 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2979 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2981 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2982 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2983 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2984 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2985 switch (opr1) {
2986 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2987 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2988 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2989 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2991 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2992 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2993 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2994 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2995 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2996 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2997 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2998 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2999 } else
3000 Handled = FALSE;
3001 break;
3002 case WINED3D_TOP_MULTIPLY_ADD:
3003 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3005 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3006 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3007 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3008 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3009 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3010 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3011 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3012 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3013 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3014 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3015 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3016 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3017 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3018 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3019 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3020 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3021 } else
3022 Handled = FALSE;
3023 break;
3024 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3025 case WINED3D_TOP_BUMPENVMAP:
3026 if (gl_info->supported[NV_TEXTURE_SHADER2])
3028 /* Technically texture shader support without register combiners is possible, but not expected to occur
3029 * on real world cards, so for now a fixme should be enough
3031 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3033 default:
3034 Handled = FALSE;
3037 if (Handled) {
3038 BOOL combineOK = TRUE;
3039 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3041 DWORD op2;
3043 if (isAlpha)
3044 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3045 else
3046 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3048 /* Note: If COMBINE4 in effect can't go back to combine! */
3049 switch (op2)
3051 case WINED3D_TOP_ADD_SMOOTH:
3052 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3053 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3054 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3055 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3056 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3057 case WINED3D_TOP_MULTIPLY_ADD:
3058 /* Ignore those implemented in both cases */
3059 switch (op)
3061 case WINED3D_TOP_SELECT_ARG1:
3062 case WINED3D_TOP_SELECT_ARG2:
3063 combineOK = FALSE;
3064 Handled = FALSE;
3065 break;
3066 default:
3067 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3068 return;
3073 if (combineOK)
3075 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3076 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3078 return;
3082 /* After all the extensions, if still unhandled, report fixme */
3083 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3087 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3089 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3090 const struct wined3d_device *device = context->swapchain->device;
3091 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3092 DWORD mapped_stage = device->texUnitMap[stage];
3093 const struct wined3d_gl_info *gl_info = context->gl_info;
3095 TRACE("Setting color op for stage %d\n", stage);
3097 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3098 if (use_ps(state)) return;
3100 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3102 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3104 if (tex_used && mapped_stage >= gl_info->limits.textures)
3106 FIXME("Attempt to enable unsupported stage!\n");
3107 return;
3109 context_active_texture(context, gl_info, mapped_stage);
3112 if (stage >= state->lowest_disabled_stage)
3114 TRACE("Stage disabled\n");
3115 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3117 /* Disable everything here */
3118 glDisable(GL_TEXTURE_2D);
3119 checkGLcall("glDisable(GL_TEXTURE_2D)");
3120 glDisable(GL_TEXTURE_3D);
3121 checkGLcall("glDisable(GL_TEXTURE_3D)");
3122 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3124 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3125 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3127 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3129 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3130 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3133 /* All done */
3134 return;
3137 /* The sampler will also activate the correct texture dimensions, so no
3138 * need to do it here if the sampler for this stage is dirty. */
3139 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3140 texture_activate_dimensions(state->textures[stage], gl_info);
3142 set_tex_op(gl_info, state, FALSE, stage,
3143 state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3144 state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3145 state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3146 state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3149 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3151 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3152 const struct wined3d_device *device = context->swapchain->device;
3153 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3154 DWORD mapped_stage = device->texUnitMap[stage];
3155 const struct wined3d_gl_info *gl_info = context->gl_info;
3156 DWORD op, arg1, arg2, arg0;
3158 TRACE("Setting alpha op for stage %d\n", stage);
3159 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3160 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3162 if (tex_used && mapped_stage >= gl_info->limits.textures)
3164 FIXME("Attempt to enable unsupported stage!\n");
3165 return;
3167 context_active_texture(context, gl_info, mapped_stage);
3170 op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3171 arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3172 arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3173 arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3175 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3177 struct wined3d_texture *texture = state->textures[0];
3178 GLenum texture_dimensions = texture->target;
3180 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3182 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3184 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3186 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3187 * properly. On the other hand applications can still use texture combiners apparently. This code
3188 * takes care that apps cannot remove the texture's alpha channel entirely.
3190 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3191 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3192 * and alpha component of diffuse color to draw things like translucent text and perform other
3193 * blending effects.
3195 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3196 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3197 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3198 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3199 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3200 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3201 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3202 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3203 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3204 * alpha.
3206 * What to do with multitexturing? So far no app has been found that uses color keying with
3207 * multitexturing */
3208 if (op == WINED3D_TOP_DISABLE)
3210 arg1 = WINED3DTA_TEXTURE;
3211 op = WINED3D_TOP_SELECT_ARG1;
3213 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3215 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3217 arg2 = WINED3DTA_TEXTURE;
3218 op = WINED3D_TOP_MODULATE;
3220 else arg1 = WINED3DTA_TEXTURE;
3222 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3224 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3226 arg1 = WINED3DTA_TEXTURE;
3227 op = WINED3D_TOP_MODULATE;
3229 else arg2 = WINED3DTA_TEXTURE;
3235 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3236 * this if block here, and the other code(color keying, texture unit selection) are the same
3238 TRACE("Setting alpha op for stage %d\n", stage);
3239 if (gl_info->supported[NV_REGISTER_COMBINERS])
3241 set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3242 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3244 else
3246 set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3250 static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3252 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3253 const struct wined3d_device *device = context->swapchain->device;
3254 const struct wined3d_gl_info *gl_info = context->gl_info;
3255 DWORD mapped_stage = device->texUnitMap[texUnit];
3256 BOOL generated;
3257 int coordIdx;
3259 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3260 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3262 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3263 return;
3266 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3267 if (mapped_stage >= gl_info->limits.textures) return;
3269 context_active_texture(context, gl_info, mapped_stage);
3270 generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3271 coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3273 set_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3274 state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3275 generated, context->last_was_rhw,
3276 device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3277 ? device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3278 : WINED3DFMT_UNKNOWN,
3279 device->frag_pipe->ffp_proj_control);
3281 /* The sampler applying function calls us if this changes */
3282 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3284 if(generated) {
3285 FIXME("Non-power2 texture being used with generated texture coords\n");
3287 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3288 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3289 if (!use_ps(state))
3291 TRACE("Non power two matrix multiply fixup\n");
3292 glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3297 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3299 unsigned int texture_idx;
3301 for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3303 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3304 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3308 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3309 GLuint *curVBO, const struct wined3d_state *state)
3311 const struct wined3d_device *device = context->swapchain->device;
3312 const struct wined3d_gl_info *gl_info = context->gl_info;
3313 unsigned int mapped_stage = 0;
3314 unsigned int textureNo = 0;
3316 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3318 int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3320 mapped_stage = device->texUnitMap[textureNo];
3321 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3323 if (mapped_stage >= gl_info->limits.texture_coords)
3325 FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3326 continue;
3329 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3331 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3333 TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3334 textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3336 if (*curVBO != e->data.buffer_object)
3338 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3339 checkGLcall("glBindBufferARB");
3340 *curVBO = e->data.buffer_object;
3343 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3344 checkGLcall("glClientActiveTextureARB");
3346 /* The coords to supply depend completely on the fvf / vertex shader */
3347 glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3348 e->data.addr + state->load_base_vertex_index * e->stride);
3349 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3351 else
3353 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3356 if (gl_info->supported[NV_REGISTER_COMBINERS])
3358 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3359 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3361 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3365 checkGLcall("loadTexCoords");
3368 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3370 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3371 const struct wined3d_device *device = context->swapchain->device;
3372 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3373 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3374 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3375 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3376 const struct wined3d_gl_info *gl_info = context->gl_info;
3377 DWORD mapped_stage = device->texUnitMap[stage];
3379 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3381 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3382 return;
3385 if (mapped_stage >= gl_info->limits.fragment_samplers)
3387 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3388 return;
3390 context_active_texture(context, gl_info, mapped_stage);
3392 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3394 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3395 * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3396 * means use the vertex position (camera-space) as the input texture coordinates
3397 * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3398 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3399 * to the TEXCOORDINDEX value
3401 switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3403 case WINED3DTSS_TCI_PASSTHRU:
3404 /* Use the specified texture coordinates contained within the
3405 * vertex format. This value resolves to zero. */
3406 glDisable(GL_TEXTURE_GEN_S);
3407 glDisable(GL_TEXTURE_GEN_T);
3408 glDisable(GL_TEXTURE_GEN_R);
3409 glDisable(GL_TEXTURE_GEN_Q);
3410 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3411 break;
3413 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3414 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3415 * as the input texture coordinates for this stage's texture transformation. This
3416 * equates roughly to EYE_LINEAR */
3418 glMatrixMode(GL_MODELVIEW);
3419 glPushMatrix();
3420 glLoadIdentity();
3421 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3422 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3423 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3424 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3425 glPopMatrix();
3426 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3428 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3429 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3430 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3431 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3433 glEnable(GL_TEXTURE_GEN_S);
3434 glEnable(GL_TEXTURE_GEN_T);
3435 glEnable(GL_TEXTURE_GEN_R);
3436 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3438 break;
3440 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3441 /* Note that NV_TEXGEN_REFLECTION support is implied when
3442 * ARB_TEXTURE_CUBE_MAP is supported */
3443 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3445 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3446 break;
3449 glMatrixMode(GL_MODELVIEW);
3450 glPushMatrix();
3451 glLoadIdentity();
3452 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3453 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3454 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3455 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3456 glPopMatrix();
3457 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3459 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3460 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3461 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3462 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3464 glEnable(GL_TEXTURE_GEN_S);
3465 glEnable(GL_TEXTURE_GEN_T);
3466 glEnable(GL_TEXTURE_GEN_R);
3467 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3469 break;
3471 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3472 /* Note that NV_TEXGEN_REFLECTION support is implied when
3473 * ARB_TEXTURE_CUBE_MAP is supported */
3474 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3476 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3477 break;
3480 glMatrixMode(GL_MODELVIEW);
3481 glPushMatrix();
3482 glLoadIdentity();
3483 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3484 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3485 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3486 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3487 glPopMatrix();
3488 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3490 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3491 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3492 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3493 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3495 glEnable(GL_TEXTURE_GEN_S);
3496 glEnable(GL_TEXTURE_GEN_T);
3497 glEnable(GL_TEXTURE_GEN_R);
3498 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3500 break;
3502 case WINED3DTSS_TCI_SPHEREMAP:
3503 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3504 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3505 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3507 glEnable(GL_TEXTURE_GEN_S);
3508 glEnable(GL_TEXTURE_GEN_T);
3509 glDisable(GL_TEXTURE_GEN_R);
3510 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3512 break;
3514 default:
3515 FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3516 state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3517 glDisable(GL_TEXTURE_GEN_S);
3518 glDisable(GL_TEXTURE_GEN_T);
3519 glDisable(GL_TEXTURE_GEN_R);
3520 glDisable(GL_TEXTURE_GEN_Q);
3521 checkGLcall("Disable texgen.");
3523 break;
3526 /* Update the texture matrix. */
3527 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3528 transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3530 if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3532 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3533 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3534 * and do all the things linked to it
3535 * TODO: Tidy that up to reload only the arrays of the changed unit
3537 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3539 unload_tex_coords(gl_info);
3540 load_tex_coords(context, &device->strided_streams, &curVBO, state);
3544 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3546 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3547 const struct wined3d_shader *ps = state->pixel_shader;
3549 if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3551 /* The pixel shader has to know the luminance scale. Do a constants
3552 * update if it isn't scheduled anyway. */
3553 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3554 && !isStateDirty(context, STATE_PIXELSHADER))
3555 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3559 static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3561 const DWORD sampler = state_id - STATE_SAMPLER(0);
3562 const struct wined3d_texture *texture = state->textures[sampler];
3564 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3566 if(!texture) return;
3567 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3568 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3569 * scaling is reapplied or removed, the texture matrix has to be reapplied
3571 * The mapped stage is already active because the sampler() function below, which is part of the
3572 * misc pipeline
3574 if (sampler < MAX_TEXTURES)
3576 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3578 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3580 const struct wined3d_device *device = context->swapchain->device;
3582 if (texIsPow2)
3583 context->lastWasPow2Texture |= 1 << sampler;
3584 else
3585 context->lastWasPow2Texture &= ~(1 << sampler);
3587 transform_texture(context, state,
3588 STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3593 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3595 const struct wined3d_device *device = context->swapchain->device;
3596 DWORD sampler = state_id - STATE_SAMPLER(0);
3597 DWORD mapped_stage = device->texUnitMap[sampler];
3598 const struct wined3d_gl_info *gl_info = context->gl_info;
3599 union {
3600 float f;
3601 DWORD d;
3602 } tmpvalue;
3604 TRACE("Sampler: %d\n", sampler);
3605 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3606 * only has to bind textures and set the per texture states
3609 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3611 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3612 return;
3615 if (mapped_stage >= gl_info->limits.combined_samplers)
3617 return;
3619 context_active_texture(context, gl_info, mapped_stage);
3621 if (state->textures[sampler])
3623 struct wined3d_texture *texture = state->textures[sampler];
3624 BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3626 texture->texture_ops->texture_bind(texture, context, srgb);
3627 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3629 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3631 tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3632 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3633 GL_TEXTURE_LOD_BIAS_EXT,
3634 tmpvalue.f);
3635 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3638 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3640 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3642 /* If color keying is enabled update the alpha test, it
3643 * depends on the existence of a color key in stage 0. */
3644 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3648 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3649 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3650 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3652 else
3654 if (sampler < state->lowest_disabled_stage)
3656 /* TODO: What should I do with pixel shaders here ??? */
3657 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3659 /* If color keying is enabled update the alpha test, it
3660 * depends on the existence of a color key in stage 0. */
3661 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3663 } /* Otherwise tex_colorop disables the stage */
3664 context_bind_texture(context, GL_NONE, 0);
3668 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3670 const struct wined3d_device *device = context->swapchain->device;
3671 BOOL use_vshader = use_vs(state);
3672 BOOL use_pshader = use_ps(state);
3673 unsigned int i;
3675 if (use_pshader)
3677 if (!context->last_was_pshader)
3679 /* Former draw without a pixel shader, some samplers may be
3680 * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3681 * make sure to enable them. */
3682 for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3684 if (!isStateDirty(context, STATE_SAMPLER(i)))
3685 sampler(context, state, STATE_SAMPLER(i));
3687 context->last_was_pshader = TRUE;
3689 else
3691 /* Otherwise all samplers were activated by the code above in
3692 * earlier draws, or by sampler() if a different texture was
3693 * bound. I don't have to do anything. */
3696 else
3698 /* Disabled the pixel shader - color ops weren't applied while it was
3699 * enabled, so re-apply them. */
3700 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3702 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3703 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3705 context->last_was_pshader = FALSE;
3708 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
3710 device->shader_backend->shader_select(context, use_pshader, use_vshader);
3712 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader))
3713 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
3717 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3719 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3720 const struct wined3d_shader *ps = state->pixel_shader;
3722 if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3724 /* The pixel shader has to know the bump env matrix. Do a constants
3725 * update if it isn't scheduled anyway. */
3726 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3727 && !isStateDirty(context, STATE_PIXELSHADER))
3728 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3732 static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3734 /* This function is called by transform_view below if the view matrix was changed too
3736 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3737 * does not always update the world matrix, only on a switch between transformed
3738 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3739 * draw, but that should be rather rare and cheaper in total.
3741 glMatrixMode(GL_MODELVIEW);
3742 checkGLcall("glMatrixMode");
3744 if(context->last_was_rhw) {
3745 glLoadIdentity();
3746 checkGLcall("glLoadIdentity()");
3748 else
3750 /* In the general case, the view matrix is the identity matrix */
3751 if (context->swapchain->device->view_ident)
3753 glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3754 checkGLcall("glLoadMatrixf");
3756 else
3758 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3759 checkGLcall("glLoadMatrixf");
3760 glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3761 checkGLcall("glMultMatrixf");
3766 static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3768 UINT index = state_id - STATE_CLIPPLANE(0);
3769 GLdouble plane[4];
3771 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= context->gl_info->limits.clipplanes)
3772 return;
3774 glMatrixMode(GL_MODELVIEW);
3775 glPushMatrix();
3777 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3778 if (!use_vs(state))
3779 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3780 else
3781 /* with vertex shaders, clip planes are not transformed in direct3d,
3782 * in OpenGL they are still transformed by the model view.
3784 glLoadIdentity();
3786 plane[0] = state->clip_planes[index].x;
3787 plane[1] = state->clip_planes[index].y;
3788 plane[2] = state->clip_planes[index].z;
3789 plane[3] = state->clip_planes[index].w;
3791 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3792 plane[0], plane[1], plane[2], plane[3]);
3793 glClipPlane(GL_CLIP_PLANE0 + index, plane);
3794 checkGLcall("glClipPlane");
3796 glPopMatrix();
3799 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3801 UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3802 GLenum glMat;
3803 TRACE("Setting world matrix %d\n", matrix);
3805 if (matrix >= context->gl_info->limits.blends)
3807 WARN("Unsupported blend matrix set\n");
3808 return;
3811 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3812 return;
3814 /* GL_MODELVIEW0_ARB: 0x1700
3815 * GL_MODELVIEW1_ARB: 0x850a
3816 * GL_MODELVIEW2_ARB: 0x8722
3817 * GL_MODELVIEW3_ARB: 0x8723
3818 * etc
3819 * GL_MODELVIEW31_ARB: 0x873F
3821 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3822 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3824 glMatrixMode(glMat);
3825 checkGLcall("glMatrixMode(glMat)");
3827 /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3828 * matrices while gl uses only 2. To avoid weighting the view matrix
3829 * incorrectly it has to be multiplied into every GL modelview matrix. */
3830 if (context->swapchain->device->view_ident)
3832 glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3833 checkGLcall("glLoadMatrixf");
3835 else
3837 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3838 checkGLcall("glLoadMatrixf");
3839 glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3840 checkGLcall("glMultMatrixf");
3844 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3846 enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3847 static unsigned int once;
3849 if (f == WINED3D_VBF_DISABLE)
3850 return;
3852 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3853 else WARN("Vertex blend flags %#x not supported.\n", f);
3856 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3858 enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3859 struct wined3d_device *device = context->swapchain->device;
3860 const struct wined3d_gl_info *gl_info = context->gl_info;
3861 static unsigned int once;
3863 switch (val)
3865 case WINED3D_VBF_1WEIGHTS:
3866 case WINED3D_VBF_2WEIGHTS:
3867 case WINED3D_VBF_3WEIGHTS:
3868 glEnable(GL_VERTEX_BLEND_ARB);
3869 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3871 /* D3D adds one more matrix which has weight (1 - sum(weights)).
3872 * This is enabled at context creation with enabling
3873 * GL_WEIGHT_SUM_UNITY_ARB. */
3874 GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3876 if (!device->vertexBlendUsed)
3878 unsigned int i;
3879 for (i = 1; i < gl_info->limits.blends; ++i)
3881 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3882 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3884 device->vertexBlendUsed = TRUE;
3886 break;
3888 case WINED3D_VBF_TWEENING:
3889 case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3890 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3891 else WARN("Vertex blend flags %#x not supported.\n", val);
3892 /* Fall through. */
3893 case WINED3D_VBF_DISABLE:
3894 glDisable(GL_VERTEX_BLEND_ARB);
3895 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3896 break;
3900 static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3902 const struct wined3d_gl_info *gl_info = context->gl_info;
3903 const struct wined3d_light_info *light = NULL;
3904 unsigned int k;
3906 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3907 * NOTE: We have to reset the positions even if the light/plane is not currently
3908 * enabled, since the call to enable it will not reset the position.
3909 * NOTE2: Apparently texture transforms do NOT need reapplying
3912 glMatrixMode(GL_MODELVIEW);
3913 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3914 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3915 checkGLcall("glLoadMatrixf(...)");
3917 /* Reset lights. TODO: Call light apply func */
3918 for (k = 0; k < gl_info->limits.lights; ++k)
3920 if (!(light = state->lights[k]))
3921 continue;
3922 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3923 checkGLcall("glLightfv posn");
3924 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3925 checkGLcall("glLightfv dirn");
3928 /* Reset Clipping Planes */
3929 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3931 if (!isStateDirty(context, STATE_CLIPPLANE(k)))
3932 clipplane(context, state, STATE_CLIPPLANE(k));
3935 if(context->last_was_rhw) {
3936 glLoadIdentity();
3937 checkGLcall("glLoadIdentity()");
3938 /* No need to update the world matrix, the identity is fine */
3939 return;
3942 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3943 * No need to do it here if the state is scheduled for update. */
3944 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
3945 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
3947 /* Avoid looping over a number of matrices if the app never used the functionality */
3948 if (context->swapchain->device->vertexBlendUsed)
3950 for (k = 1; k < gl_info->limits.blends; ++k)
3952 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
3953 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
3958 static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3960 glMatrixMode(GL_PROJECTION);
3961 checkGLcall("glMatrixMode(GL_PROJECTION)");
3963 /* There are a couple of additional things we have to take into account
3964 * here besides the projection transformation itself:
3965 * - We need to flip along the y-axis in case of offscreen rendering.
3966 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
3967 * - D3D coordinates refer to pixel centers while GL coordinates refer
3968 * to pixel corners.
3969 * - D3D has a top-left filling convention. We need to maintain this
3970 * even after the y-flip mentioned above.
3971 * In order to handle the last two points, we translate by
3972 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
3973 * translating slightly less than half a pixel. We want the difference to
3974 * be large enough that it doesn't get lost due to rounding inside the
3975 * driver, but small enough to prevent it from interfering with any
3976 * anti-aliasing. */
3978 if (context->last_was_rhw)
3980 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
3981 double x = state->viewport.x;
3982 double y = state->viewport.y;
3983 double w = state->viewport.width;
3984 double h = state->viewport.height;
3985 double x_scale = 2.0 / w;
3986 double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
3987 double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
3988 double y_offset = context->render_offscreen
3989 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
3990 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
3991 const GLdouble projection[] =
3993 x_scale, 0.0, 0.0, 0.0,
3994 0.0, y_scale, 0.0, 0.0,
3995 0.0, 0.0, 2.0, 0.0,
3996 x_offset, y_offset, -1.0, 1.0,
3999 glLoadMatrixd(projection);
4000 checkGLcall("glLoadMatrixd");
4002 else
4004 double y_scale = context->render_offscreen ? -1.0 : 1.0;
4005 double x_offset = (63.0 / 64.0) / state->viewport.width;
4006 double y_offset = context->render_offscreen
4007 ? (63.0 / 64.0) / state->viewport.height
4008 : -(63.0 / 64.0) / state->viewport.height;
4009 const GLdouble projection[] =
4011 1.0, 0.0, 0.0, 0.0,
4012 0.0, y_scale, 0.0, 0.0,
4013 0.0, 0.0, 2.0, 0.0,
4014 x_offset, y_offset, -1.0, 1.0,
4017 glLoadMatrixd(projection);
4018 checkGLcall("glLoadMatrixd");
4020 glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4021 checkGLcall("glLoadMatrixf");
4025 /* This should match any arrays loaded in load_vertex_data.
4026 * TODO: Only load / unload arrays if we have to. */
4027 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4029 glDisableClientState(GL_VERTEX_ARRAY);
4030 glDisableClientState(GL_NORMAL_ARRAY);
4031 glDisableClientState(GL_COLOR_ARRAY);
4032 if (gl_info->supported[EXT_SECONDARY_COLOR])
4034 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4036 if (gl_info->supported[ARB_VERTEX_BLEND])
4038 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4040 unload_tex_coords(gl_info);
4043 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4045 const struct wined3d_gl_info *gl_info = context->gl_info;
4047 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4048 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4050 context->numbered_array_mask &= ~(1 << i);
4053 /* This should match any arrays loaded in loadNumberedArrays
4054 * TODO: Only load / unload arrays if we have to. */
4055 static void unload_numbered_arrays(struct wined3d_context *context)
4057 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4058 int i;
4060 for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4061 unload_numbered_array(context, i);
4065 static void load_numbered_arrays(struct wined3d_context *context,
4066 const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4068 struct wined3d_device *device = context->swapchain->device;
4069 const struct wined3d_gl_info *gl_info = context->gl_info;
4070 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4071 int i;
4073 /* Default to no instancing */
4074 device->instancedDraw = FALSE;
4076 for (i = 0; i < MAX_ATTRIBS; i++)
4078 const struct wined3d_stream_state *stream;
4080 if (!(stream_info->use_map & (1 << i)))
4082 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4083 continue;
4086 stream = &state->streams[stream_info->elements[i].stream_idx];
4088 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4089 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4091 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4092 device->instancedDraw = TRUE;
4093 continue;
4096 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4098 if (stream_info->elements[i].stride)
4100 if (curVBO != stream_info->elements[i].data.buffer_object)
4102 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4103 checkGLcall("glBindBufferARB");
4104 curVBO = stream_info->elements[i].data.buffer_object;
4106 /* Use the VBO to find out if a vertex buffer exists, not the vb
4107 * pointer. vb can point to a user pointer data blob. In that case
4108 * curVBO will be 0. If there is a vertex buffer but no vbo we
4109 * won't be load converted attributes anyway. */
4110 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4111 stream_info->elements[i].format->gl_vtx_type,
4112 stream_info->elements[i].format->gl_normalized,
4113 stream_info->elements[i].stride, stream_info->elements[i].data.addr
4114 + state->load_base_vertex_index * stream_info->elements[i].stride));
4116 if (!(context->numbered_array_mask & (1 << i)))
4118 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4119 context->numbered_array_mask |= (1 << i);
4122 else
4124 /* Stride = 0 means always the same values.
4125 * glVertexAttribPointerARB doesn't do that. Instead disable the
4126 * pointer and set up the attribute statically. But we have to
4127 * figure out the system memory address. */
4128 const BYTE *ptr = stream_info->elements[i].data.addr;
4129 if (stream_info->elements[i].data.buffer_object)
4131 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4134 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4136 switch (stream_info->elements[i].format->id)
4138 case WINED3DFMT_R32_FLOAT:
4139 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4140 break;
4141 case WINED3DFMT_R32G32_FLOAT:
4142 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4143 break;
4144 case WINED3DFMT_R32G32B32_FLOAT:
4145 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4146 break;
4147 case WINED3DFMT_R32G32B32A32_FLOAT:
4148 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4149 break;
4151 case WINED3DFMT_R8G8B8A8_UINT:
4152 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4153 break;
4154 case WINED3DFMT_B8G8R8A8_UNORM:
4155 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4157 const DWORD *src = (const DWORD *)ptr;
4158 DWORD c = *src & 0xff00ff00;
4159 c |= (*src & 0xff0000) >> 16;
4160 c |= (*src & 0xff) << 16;
4161 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4162 break;
4164 /* else fallthrough */
4165 case WINED3DFMT_R8G8B8A8_UNORM:
4166 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4167 break;
4169 case WINED3DFMT_R16G16_SINT:
4170 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4171 break;
4172 case WINED3DFMT_R16G16B16A16_SINT:
4173 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4174 break;
4176 case WINED3DFMT_R16G16_SNORM:
4178 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4179 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4180 break;
4182 case WINED3DFMT_R16G16_UNORM:
4184 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4185 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4186 break;
4188 case WINED3DFMT_R16G16B16A16_SNORM:
4189 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4190 break;
4191 case WINED3DFMT_R16G16B16A16_UNORM:
4192 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4193 break;
4195 case WINED3DFMT_R10G10B10A2_UINT:
4196 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4197 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4198 break;
4199 case WINED3DFMT_R10G10B10A2_SNORM:
4200 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4201 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4202 break;
4204 case WINED3DFMT_R16G16_FLOAT:
4205 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4206 * byte float according to the IEEE standard
4208 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4209 break;
4210 case WINED3DFMT_R16G16B16A16_FLOAT:
4211 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4212 break;
4214 default:
4215 ERR("Unexpected declaration in stride 0 attributes\n");
4216 break;
4221 checkGLcall("Loading numbered arrays");
4224 static void load_vertex_data(const struct wined3d_context *context,
4225 const struct wined3d_stream_info *si, const struct wined3d_state *state)
4227 struct wined3d_device *device = context->swapchain->device;
4228 const struct wined3d_gl_info *gl_info = context->gl_info;
4229 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4230 const struct wined3d_stream_info_element *e;
4232 TRACE("Using fast vertex array code\n");
4234 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4235 device->instancedDraw = FALSE;
4237 /* Blend Data ---------------------------------------------- */
4238 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4239 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4241 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4243 if (gl_info->supported[ARB_VERTEX_BLEND])
4245 TRACE("Blend %u %p %u\n", e->format->component_count,
4246 e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4248 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4249 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4251 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4253 if (curVBO != e->data.buffer_object)
4255 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4256 checkGLcall("glBindBufferARB");
4257 curVBO = e->data.buffer_object;
4260 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4261 e->format->gl_vtx_format,
4262 e->format->gl_vtx_type,
4263 e->stride,
4264 e->data.addr + state->load_base_vertex_index * e->stride);
4265 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4266 e->data.addr + state->load_base_vertex_index * e->stride));
4268 checkGLcall("glWeightPointerARB");
4270 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4272 static BOOL warned;
4273 if (!warned)
4275 FIXME("blendMatrixIndices support\n");
4276 warned = TRUE;
4279 } else {
4280 /* TODO: support blends in drawStridedSlow
4281 * No need to write a FIXME here, this is done after the general vertex decl decoding
4283 WARN("unsupported blending in openGl\n");
4286 else
4288 if (gl_info->supported[ARB_VERTEX_BLEND])
4290 static const GLbyte one = 1;
4291 GL_EXTCALL(glWeightbvARB(1, &one));
4292 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4296 /* Point Size ----------------------------------------------*/
4297 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4299 /* no such functionality in the fixed function GL pipeline */
4300 TRACE("Cannot change ptSize here in openGl\n");
4301 /* TODO: Implement this function in using shaders if they are available */
4304 /* Vertex Pointers -----------------------------------------*/
4305 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4307 e = &si->elements[WINED3D_FFP_POSITION];
4309 if (curVBO != e->data.buffer_object)
4311 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4312 checkGLcall("glBindBufferARB");
4313 curVBO = e->data.buffer_object;
4316 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4317 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4318 e->data.addr + state->load_base_vertex_index * e->stride);
4319 glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4320 e->data.addr + state->load_base_vertex_index * e->stride);
4321 checkGLcall("glVertexPointer(...)");
4322 glEnableClientState(GL_VERTEX_ARRAY);
4323 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4326 /* Normals -------------------------------------------------*/
4327 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4329 e = &si->elements[WINED3D_FFP_NORMAL];
4331 if (curVBO != e->data.buffer_object)
4333 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4334 checkGLcall("glBindBufferARB");
4335 curVBO = e->data.buffer_object;
4338 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4339 e->data.addr + state->load_base_vertex_index * e->stride);
4340 glNormalPointer(e->format->gl_vtx_type, e->stride,
4341 e->data.addr + state->load_base_vertex_index * e->stride);
4342 checkGLcall("glNormalPointer(...)");
4343 glEnableClientState(GL_NORMAL_ARRAY);
4344 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4346 } else {
4347 glNormal3f(0, 0, 0);
4348 checkGLcall("glNormal3f(0, 0, 0)");
4351 /* Diffuse Colour --------------------------------------------*/
4352 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4354 e = &si->elements[WINED3D_FFP_DIFFUSE];
4356 if (curVBO != e->data.buffer_object)
4358 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4359 checkGLcall("glBindBufferARB");
4360 curVBO = e->data.buffer_object;
4363 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4364 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4365 e->data.addr + state->load_base_vertex_index * e->stride);
4366 glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4367 e->data.addr + state->load_base_vertex_index * e->stride);
4368 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4369 glEnableClientState(GL_COLOR_ARRAY);
4370 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4372 } else {
4373 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4374 checkGLcall("glColor4f(1, 1, 1, 1)");
4377 /* Specular Colour ------------------------------------------*/
4378 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4380 TRACE("setting specular colour\n");
4382 e = &si->elements[WINED3D_FFP_SPECULAR];
4384 if (gl_info->supported[EXT_SECONDARY_COLOR])
4386 GLenum type = e->format->gl_vtx_type;
4387 GLint format = e->format->gl_vtx_format;
4389 if (curVBO != e->data.buffer_object)
4391 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4392 checkGLcall("glBindBufferARB");
4393 curVBO = e->data.buffer_object;
4396 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4398 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4399 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4400 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4401 * 4 component secondary colors use it
4403 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4404 e->data.addr + state->load_base_vertex_index * e->stride);
4405 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4406 e->data.addr + state->load_base_vertex_index * e->stride));
4407 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4409 else
4411 switch(type)
4413 case GL_UNSIGNED_BYTE:
4414 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4415 e->data.addr + state->load_base_vertex_index * e->stride);
4416 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4417 e->data.addr + state->load_base_vertex_index * e->stride));
4418 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4419 break;
4421 default:
4422 FIXME("Add 4 component specular color pointers for type %x\n", type);
4423 /* Make sure that the right color component is dropped */
4424 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4425 e->data.addr + state->load_base_vertex_index * e->stride);
4426 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4427 e->data.addr + state->load_base_vertex_index * e->stride));
4428 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4431 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4432 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4434 else
4436 WARN("Specular colour is not supported in this GL implementation.\n");
4439 else
4441 if (gl_info->supported[EXT_SECONDARY_COLOR])
4443 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4444 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4446 else
4448 WARN("Specular colour is not supported in this GL implementation.\n");
4452 /* Texture coords -------------------------------------------*/
4453 load_tex_coords(context, si, &curVBO, state);
4456 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4458 const struct wined3d_device *device = context->swapchain->device;
4459 BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4460 BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4462 if (isStateDirty(context, STATE_VDECL)) return;
4463 if (context->numberedArraysLoaded && !load_numbered)
4465 unload_numbered_arrays(context);
4466 context->numberedArraysLoaded = FALSE;
4467 context->numbered_array_mask = 0;
4469 else if (context->namedArraysLoaded)
4471 unload_vertex_data(context->gl_info);
4472 context->namedArraysLoaded = FALSE;
4475 if (load_numbered)
4477 TRACE("Loading numbered arrays\n");
4478 load_numbered_arrays(context, &device->strided_streams, state);
4479 context->numberedArraysLoaded = TRUE;
4481 else if (load_named)
4483 TRACE("Loading vertex data\n");
4484 load_vertex_data(context, &device->strided_streams, state);
4485 context->namedArraysLoaded = TRUE;
4489 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4491 if (isStateDirty(context, STATE_STREAMSRC))
4492 return;
4493 streamsrc(context, state, STATE_STREAMSRC);
4496 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4498 const struct wined3d_device *device = context->swapchain->device;
4499 const struct wined3d_gl_info *gl_info = context->gl_info;
4500 BOOL useVertexShaderFunction = use_vs(state);
4501 BOOL usePixelShaderFunction = use_ps(state);
4502 BOOL updateFog = FALSE;
4503 BOOL transformed;
4504 BOOL wasrhw = context->last_was_rhw;
4505 unsigned int i;
4507 transformed = device->strided_streams.position_transformed;
4508 if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4509 updateFog = TRUE;
4511 context->last_was_rhw = transformed;
4513 /* Don't have to apply the matrices when vertex shaders are used. When
4514 * vshaders are turned off this function will be called again anyway to
4515 * make sure they're properly set. */
4516 if (!useVertexShaderFunction)
4518 /* TODO: Move this mainly to the viewport state and only apply when
4519 * the vp has changed or transformed / untransformed was switched. */
4520 if (wasrhw != context->last_was_rhw
4521 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4522 && !isStateDirty(context, STATE_VIEWPORT))
4523 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4524 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4525 * mode.
4527 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4528 * this check will fail and the matrix not applied again. This is OK because a simple
4529 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4530 * needs of the vertex declaration.
4532 * World and view matrix go into the same gl matrix, so only apply them when neither is
4533 * dirty
4535 if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4536 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4537 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4538 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4539 state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4540 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4541 state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4543 if (context->last_was_vshader)
4545 updateFog = TRUE;
4547 if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4548 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4550 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4552 clipplane(context, state, STATE_CLIPPLANE(i));
4555 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4556 state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4558 else
4560 if(!context->last_was_vshader) {
4561 static BOOL warned = FALSE;
4562 if(!device->vs_clipping) {
4563 /* Disable all clip planes to get defined results on all drivers. See comment in the
4564 * state_clipping state handler
4566 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4568 glDisable(GL_CLIP_PLANE0 + i);
4569 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4572 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4574 FIXME("Clipping not supported with vertex shaders\n");
4575 warned = TRUE;
4578 if (wasrhw)
4580 /* Apply the transform matrices when switching from rhw
4581 * drawing to vertex shaders. Vertex shaders themselves do
4582 * not need it, but the matrices are not reapplied
4583 * automatically when switching back from vertex shaders to
4584 * fixed function processing. So make sure we leave the fixed
4585 * function vertex processing states back in a sane state
4586 * before switching to shaders. */
4587 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4588 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4589 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4590 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4592 updateFog = TRUE;
4594 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4595 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4596 * device->vs_clipping is false.
4598 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4600 clipplane(context, state, STATE_CLIPPLANE(i));
4605 /* Vertex and pixel shaders are applied together, so let the last dirty
4606 * state do the application. */
4607 if (!isStateDirty(context, STATE_PIXELSHADER))
4609 device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4611 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)
4612 && (useVertexShaderFunction || usePixelShaderFunction))
4613 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4616 context->last_was_vshader = useVertexShaderFunction;
4618 if (updateFog)
4619 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4621 if (!useVertexShaderFunction)
4623 unsigned int i;
4625 for (i = 0; i < MAX_TEXTURES; ++i)
4627 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4628 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4632 if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4633 state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4636 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4638 const struct wined3d_surface *target = state->fb->render_targets[0];
4639 struct wined3d_viewport vp = state->viewport;
4641 if (vp.width > target->resource.width)
4642 vp.width = target->resource.width;
4643 if (vp.height > target->resource.height)
4644 vp.height = target->resource.height;
4646 glDepthRange(vp.min_z, vp.max_z);
4647 checkGLcall("glDepthRange");
4648 /* Note: GL requires lower left, DirectX supplies upper left. This is
4649 * reversed when using offscreen rendering. */
4650 if (context->render_offscreen)
4652 glViewport(vp.x, vp.y, vp.width, vp.height);
4654 else
4656 UINT width, height;
4658 target->get_drawable_size(context, &width, &height);
4659 glViewport(vp.x, (height - (vp.y + vp.height)),
4660 vp.width, vp.height);
4663 checkGLcall("glViewport");
4666 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4668 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4669 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4670 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4671 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4672 /* Update the position fixup. */
4673 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
4674 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4677 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4679 UINT Index = state_id - STATE_ACTIVELIGHT(0);
4680 const struct wined3d_light_info *lightInfo = state->lights[Index];
4682 if (!lightInfo)
4684 glDisable(GL_LIGHT0 + Index);
4685 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4687 else
4689 float quad_att;
4690 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4692 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4693 glMatrixMode(GL_MODELVIEW);
4694 glPushMatrix();
4695 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4697 /* Diffuse: */
4698 colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4699 colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4700 colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4701 colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4702 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4703 checkGLcall("glLightfv");
4705 /* Specular */
4706 colRGBA[0] = lightInfo->OriginalParms.specular.r;
4707 colRGBA[1] = lightInfo->OriginalParms.specular.g;
4708 colRGBA[2] = lightInfo->OriginalParms.specular.b;
4709 colRGBA[3] = lightInfo->OriginalParms.specular.a;
4710 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4711 checkGLcall("glLightfv");
4713 /* Ambient */
4714 colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4715 colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4716 colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4717 colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4718 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4719 checkGLcall("glLightfv");
4721 if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4722 quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4723 else
4724 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4726 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4727 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4728 * Attenuation0 to NaN and crashes in the gl lib
4731 switch (lightInfo->OriginalParms.type)
4733 case WINED3D_LIGHT_POINT:
4734 /* Position */
4735 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4736 checkGLcall("glLightfv");
4737 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4738 checkGLcall("glLightf");
4739 /* Attenuation - Are these right? guessing... */
4740 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4741 checkGLcall("glLightf");
4742 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4743 checkGLcall("glLightf");
4744 if (quad_att < lightInfo->OriginalParms.attenuation2)
4745 quad_att = lightInfo->OriginalParms.attenuation2;
4746 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4747 checkGLcall("glLightf");
4748 /* FIXME: Range */
4749 break;
4751 case WINED3D_LIGHT_SPOT:
4752 /* Position */
4753 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4754 checkGLcall("glLightfv");
4755 /* Direction */
4756 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4757 checkGLcall("glLightfv");
4758 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4759 checkGLcall("glLightf");
4760 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4761 checkGLcall("glLightf");
4762 /* Attenuation - Are these right? guessing... */
4763 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4764 checkGLcall("glLightf");
4765 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4766 checkGLcall("glLightf");
4767 if (quad_att < lightInfo->OriginalParms.attenuation2)
4768 quad_att = lightInfo->OriginalParms.attenuation2;
4769 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4770 checkGLcall("glLightf");
4771 /* FIXME: Range */
4772 break;
4774 case WINED3D_LIGHT_DIRECTIONAL:
4775 /* Direction */
4776 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4777 checkGLcall("glLightfv");
4778 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4779 checkGLcall("glLightf");
4780 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4781 checkGLcall("glLightf");
4782 break;
4784 default:
4785 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4788 /* Restore the modelview matrix */
4789 glPopMatrix();
4791 glEnable(GL_LIGHT0 + Index);
4792 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4796 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4798 const RECT *r = &state->scissor_rect;
4800 /* Warning: glScissor uses window coordinates, not viewport coordinates,
4801 * so our viewport correction does not apply. Warning2: Even in windowed
4802 * mode the coords are relative to the window, not the screen. */
4803 TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4805 if (context->render_offscreen)
4807 glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4809 else
4811 const struct wined3d_surface *target = state->fb->render_targets[0];
4812 UINT height;
4813 UINT width;
4815 target->get_drawable_size(context, &width, &height);
4816 glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4818 checkGLcall("glScissor");
4821 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4823 const struct wined3d_stream_info *stream_info = &context->swapchain->device->strided_streams;
4824 const struct wined3d_gl_info *gl_info = context->gl_info;
4826 if (state->user_stream || !state->index_buffer || !stream_info->all_vbo)
4828 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4830 else
4832 struct wined3d_buffer *ib = state->index_buffer;
4833 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4837 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4839 if (context->render_offscreen)
4841 glFrontFace(GL_CCW);
4842 checkGLcall("glFrontFace(GL_CCW)");
4843 } else {
4844 glFrontFace(GL_CW);
4845 checkGLcall("glFrontFace(GL_CW)");
4849 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4851 static BOOL warned;
4853 if (!warned)
4855 WARN("Point sprite coordinate origin switching not supported.\n");
4856 warned = TRUE;
4860 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4862 const struct wined3d_gl_info *gl_info = context->gl_info;
4863 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4865 if (glPointParameteri)
4867 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin);
4868 checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4870 else if (gl_info->supported[NV_POINT_SPRITE])
4872 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4873 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4877 const struct StateEntryTemplate misc_state_template[] = {
4878 { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4879 { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4880 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4881 { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4882 { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4883 { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4884 { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4885 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4886 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4887 { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4888 { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
4889 { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
4890 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4891 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4892 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4893 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4895 /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4896 * vshader loadings are untied from each other
4898 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4899 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4900 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4901 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4902 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4903 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4904 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4905 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4906 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4907 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4908 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4909 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4910 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4911 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4912 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4913 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4914 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4915 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4916 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4917 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4918 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4919 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4920 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4921 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4922 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4923 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4924 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4925 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4926 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4927 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4928 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4929 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4930 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4931 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4932 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4933 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4934 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4935 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4936 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4937 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4938 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4939 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4940 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4941 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4942 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4943 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4944 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4945 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4946 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4947 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4949 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
4950 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
4951 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
4952 { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
4953 { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
4954 { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
4955 { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
4956 { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
4957 { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
4958 { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
4959 { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
4960 { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
4961 { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
4962 { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
4963 { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
4964 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
4965 { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4966 { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4967 { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4968 { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
4969 { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
4970 { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
4971 { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
4972 { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
4973 { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
4974 { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
4975 { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
4976 { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
4977 { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
4978 { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
4979 { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
4980 { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4981 { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4982 { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4983 { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4984 { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4985 { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4986 { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4987 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
4988 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
4989 { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4990 { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4991 { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4992 { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4993 { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4994 { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4995 { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4996 { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4997 { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4998 { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
4999 { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5000 { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5001 { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5003 { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5004 { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5005 { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5006 { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5007 { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5008 { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5009 { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5010 { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5011 { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5012 { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5013 { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5014 { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5015 { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5016 { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5017 { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5018 { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5019 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5020 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5021 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5022 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5023 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5024 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
5025 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5026 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5027 { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5028 { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5029 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5030 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5031 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5032 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5033 { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5034 { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5035 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5036 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5037 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5038 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5039 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5040 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5042 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5044 { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5045 /* Samplers */
5046 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5047 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5048 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5049 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5050 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5051 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5052 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5053 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5054 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5055 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5056 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5057 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5058 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5059 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5060 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5061 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5062 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5063 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5064 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5065 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5066 { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
5067 { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
5068 { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
5069 { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
5070 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5073 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5074 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5075 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5076 { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5077 { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5078 /* Clip planes */
5079 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5080 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5081 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5082 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5083 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5084 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5085 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5086 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5087 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5088 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5089 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5090 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5091 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5092 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5093 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5094 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5095 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5096 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5097 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5098 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5099 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5100 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5101 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5102 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5103 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5104 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5105 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5106 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5107 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5108 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5109 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5110 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5111 /* Lights */
5112 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5113 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5114 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5115 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5116 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5117 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5118 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5119 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5120 /* Viewport */
5121 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5122 /* Transform states follow */
5123 { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5124 { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5125 { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5126 { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5127 { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5128 { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5129 { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5130 { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5131 { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5132 { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5133 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5134 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5135 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5136 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5137 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5138 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5139 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5140 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5141 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5142 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5143 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5144 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5145 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5146 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5147 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5148 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5149 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5150 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5151 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5152 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5153 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5154 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5155 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5156 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5157 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5158 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5159 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5160 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5161 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5162 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5163 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5164 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5165 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5166 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5167 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5168 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5169 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5170 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5171 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5172 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5173 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5174 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5175 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5176 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5177 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5178 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5179 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5180 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5181 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5182 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5183 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5184 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5185 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5186 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5187 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5188 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5189 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5190 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5191 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5192 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5193 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5194 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5195 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5390 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5391 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5392 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5393 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5394 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5395 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5396 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5397 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5400 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5401 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5402 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5403 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5405 /* Fog */
5406 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5407 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5408 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5409 { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5410 { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5411 { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5412 { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5413 { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5414 { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5415 { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5416 { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5417 { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5418 { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5419 { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5420 { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5421 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5422 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5423 { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5424 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5425 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5426 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5427 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5428 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5429 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5430 { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5431 { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5432 { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5433 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5434 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5435 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5436 { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5437 { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5439 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5440 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5441 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5443 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5444 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5445 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5446 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5447 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5448 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5449 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5450 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5451 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5452 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5453 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5454 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5455 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5456 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5457 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5458 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5459 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5460 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5461 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5462 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5463 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5464 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5465 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5466 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5467 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5470 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5471 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5472 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5473 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5474 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5475 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5476 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5477 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5478 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5479 { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5480 { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5481 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5482 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5483 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5484 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5485 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5486 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5487 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5488 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5489 { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5490 { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5491 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5492 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5493 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5494 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5495 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5496 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5497 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5498 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5499 { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5500 { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5501 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5502 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5503 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5504 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5505 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5506 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5507 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5508 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5509 { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5510 { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5511 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5512 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5513 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5514 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5515 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5516 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5517 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5518 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5519 { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5520 { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5521 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5522 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5523 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5524 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5525 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5526 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5527 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5528 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5529 { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5530 { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5531 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5532 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5533 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5534 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5535 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5536 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5537 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5538 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5539 { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5540 { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5541 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5542 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5543 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5544 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5545 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5546 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5547 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5548 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5549 { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5550 { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5551 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5552 { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5553 { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5554 { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5555 { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5556 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5557 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5558 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5559 { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5560 { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5561 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5562 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5563 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5564 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5565 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5566 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5567 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5568 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5569 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5572 /* Context activation and GL locking are done by the caller. */
5573 static void ffp_enable(BOOL enable) {}
5575 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5577 caps->PrimitiveMiscCaps = 0;
5578 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5579 | WINED3DTEXOPCAPS_ADDSIGNED
5580 | WINED3DTEXOPCAPS_ADDSIGNED2X
5581 | WINED3DTEXOPCAPS_MODULATE
5582 | WINED3DTEXOPCAPS_MODULATE2X
5583 | WINED3DTEXOPCAPS_MODULATE4X
5584 | WINED3DTEXOPCAPS_SELECTARG1
5585 | WINED3DTEXOPCAPS_SELECTARG2
5586 | WINED3DTEXOPCAPS_DISABLE;
5588 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5589 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5590 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5592 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5593 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5594 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5595 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5596 | WINED3DTEXOPCAPS_LERP
5597 | WINED3DTEXOPCAPS_SUBTRACT;
5599 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5600 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5602 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5603 | WINED3DTEXOPCAPS_MULTIPLYADD
5604 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5605 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5606 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5608 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5609 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5611 caps->MaxTextureBlendStages = gl_info->limits.textures;
5612 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5615 static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; }
5616 static void ffp_fragment_free(struct wined3d_device *device) {}
5617 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5619 if (TRACE_ON(d3d))
5621 TRACE("Checking support for fixup:\n");
5622 dump_color_fixup_desc(fixup);
5625 /* We only support identity conversions. */
5626 if (is_identity_fixup(fixup))
5628 TRACE("[OK]\n");
5629 return TRUE;
5632 TRACE("[FAILED]\n");
5633 return FALSE;
5636 const struct fragment_pipeline ffp_fragment_pipeline = {
5637 ffp_enable,
5638 ffp_fragment_get_caps,
5639 ffp_fragment_alloc,
5640 ffp_fragment_free,
5641 ffp_color_fixup_supported,
5642 ffp_fragmentstate_template,
5643 FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5646 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5648 unsigned int i;
5649 for(i = 0; funcs[i]; i++);
5650 return i;
5653 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5655 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5656 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5659 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5661 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5662 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5663 context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5666 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5668 unsigned int start, last, i;
5670 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5671 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5672 for (i = start; i <= last; ++i)
5674 state_table[i].representative = 0;
5675 state_table[i].apply = state_undefined;
5678 start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
5679 last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5680 for (i = start; i <= last; ++i)
5682 state_table[i].representative = 0;
5683 state_table[i].apply = state_undefined;
5686 start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5687 last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5688 for (i = start; i <= last; ++i)
5690 state_table[i].representative = 0;
5691 state_table[i].apply = state_undefined;
5695 static void validate_state_table(struct StateEntry *state_table)
5697 static const struct
5699 DWORD first;
5700 DWORD last;
5702 rs_holes[] =
5704 { 1, 1},
5705 { 3, 3},
5706 { 17, 18},
5707 { 21, 21},
5708 { 42, 45},
5709 { 47, 47},
5710 { 61, 127},
5711 {149, 150},
5712 {169, 169},
5713 {177, 177},
5714 {196, 197},
5715 { 0, 0},
5717 static const DWORD simple_states[] =
5719 STATE_MATERIAL,
5720 STATE_VDECL,
5721 STATE_STREAMSRC,
5722 STATE_INDEXBUFFER,
5723 STATE_VERTEXSHADERCONSTANT,
5724 STATE_PIXELSHADERCONSTANT,
5725 STATE_VSHADER,
5726 STATE_PIXELSHADER,
5727 STATE_VIEWPORT,
5728 STATE_SCISSORRECT,
5729 STATE_FRONTFACE,
5730 STATE_POINTSPRITECOORDORIGIN,
5731 STATE_BASEVERTEXINDEX,
5732 STATE_FRAMEBUFFER
5734 unsigned int i, current;
5736 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5738 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5740 if (!state_table[i].representative)
5741 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5743 else if (state_table[i].representative)
5744 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5746 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5749 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5751 if (!state_table[simple_states[i]].representative)
5752 ERR("State %s (%#x) should have a representative.\n",
5753 debug_d3dstate(simple_states[i]), simple_states[i]);
5756 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5758 DWORD rep = state_table[i].representative;
5759 if (rep)
5761 if (state_table[rep].representative != rep)
5763 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5764 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5765 state_table[i].representative = 0;
5768 if (rep != i)
5770 if (state_table[i].apply)
5771 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5773 else if (!state_table[i].apply)
5775 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5781 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5782 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5783 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5785 unsigned int i, type, handlers;
5786 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5787 const struct StateEntryTemplate *cur;
5788 BOOL set[STATE_HIGHEST + 1];
5790 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5792 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5793 StateTable[i].representative = 0;
5794 StateTable[i].apply = state_undefined;
5797 for(type = 0; type < 3; type++) {
5798 /* This switch decides the order in which the states are applied */
5799 switch(type) {
5800 case 0: cur = misc; break;
5801 case 1: cur = fragment->states; break;
5802 case 2: cur = vertex; break;
5803 default: cur = NULL; /* Stupid compiler */
5805 if(!cur) continue;
5807 /* GL extension filtering should not prevent multiple handlers being applied from different
5808 * pipeline parts
5810 memset(set, 0, sizeof(set));
5812 for(i = 0; cur[i].state; i++) {
5813 APPLYSTATEFUNC *funcs_array;
5815 /* Only use the first matching state with the available extension from one template.
5816 * e.g.
5817 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5818 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5820 * if GL_XYZ_fancy is supported, ignore the 2nd line
5822 if(set[cur[i].state]) continue;
5823 /* Skip state lines depending on unsupported extensions */
5824 if (!gl_info->supported[cur[i].extension]) continue;
5825 set[cur[i].state] = TRUE;
5826 /* In some cases having an extension means that nothing has to be
5827 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5828 * supported, the texture coordinate fixup can be ignored. If the
5829 * apply function is used, mark the state set(done above) to prevent
5830 * applying later lines, but do not record anything in the state
5831 * table
5833 if (!cur[i].content.representative) continue;
5835 handlers = num_handlers(multistate_funcs[cur[i].state]);
5836 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5837 switch(handlers) {
5838 case 0:
5839 StateTable[cur[i].state].apply = cur[i].content.apply;
5840 break;
5841 case 1:
5842 StateTable[cur[i].state].apply = multistate_apply_2;
5843 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5845 sizeof(**dev_multistate_funcs) * 2);
5846 if (!dev_multistate_funcs[cur[i].state]) {
5847 goto out_of_mem;
5850 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5851 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5852 break;
5853 case 2:
5854 StateTable[cur[i].state].apply = multistate_apply_3;
5855 funcs_array = HeapReAlloc(GetProcessHeap(),
5857 dev_multistate_funcs[cur[i].state],
5858 sizeof(**dev_multistate_funcs) * 3);
5859 if (!funcs_array) {
5860 goto out_of_mem;
5863 dev_multistate_funcs[cur[i].state] = funcs_array;
5864 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5865 break;
5866 default:
5867 ERR("Unexpected amount of state handlers for state %u: %u\n",
5868 cur[i].state, handlers + 1);
5871 if(StateTable[cur[i].state].representative &&
5872 StateTable[cur[i].state].representative != cur[i].content.representative) {
5873 FIXME("State %u has different representatives in different pipeline parts\n",
5874 cur[i].state);
5876 StateTable[cur[i].state].representative = cur[i].content.representative;
5880 prune_invalid_states(StateTable, gl_info);
5881 validate_state_table(StateTable);
5883 return WINED3D_OK;
5885 out_of_mem:
5886 for (i = 0; i <= STATE_HIGHEST; ++i) {
5887 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5890 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5892 return E_OUTOFMEMORY;