wined3d: Remove an outdated comment in state_zwritenable().
[wine.git] / dlls / wined3d / state.c
blobc0e0c0e3ef8d7f58709d25de638ef5c3c4da6754
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_texture *texture = state->textures[0];
532 GLenum texture_dimensions = texture->target;
534 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
536 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
538 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
539 enable_ckey = TRUE;
543 if (enable_ckey || context->last_was_ckey)
544 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
545 context->last_was_ckey = enable_ckey;
547 if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
548 || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
550 glEnable(GL_ALPHA_TEST);
551 checkGLcall("glEnable GL_ALPHA_TEST");
552 } else {
553 glDisable(GL_ALPHA_TEST);
554 checkGLcall("glDisable GL_ALPHA_TEST");
555 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
556 * enable call
558 return;
561 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
563 glParm = GL_NOTEQUAL;
564 ref = 0.0f;
566 else
568 ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
569 glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
571 if(glParm) {
572 glAlphaFunc(glParm, ref);
573 checkGLcall("glAlphaFunc");
577 static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
579 const struct wined3d_device *device = context->swapchain->device;
581 /* Vertex and pixel shader states will call a shader upload, don't do
582 * anything as long one of them has an update pending. */
583 if (isStateDirty(context, STATE_VDECL)
584 || isStateDirty(context, STATE_PIXELSHADER))
585 return;
587 device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
590 static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
592 DWORD enable = 0xFFFFFFFF;
593 DWORD disable = 0x00000000;
595 if (use_vs(state))
597 const struct wined3d_device *device = context->swapchain->device;
599 if (!device->vs_clipping)
601 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
602 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
603 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
604 * of that - don't do anything here and keep them disabled
606 if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
608 static BOOL warned = FALSE;
609 if(!warned) {
610 FIXME("Clipping not supported with vertex shaders\n");
611 warned = TRUE;
614 return;
617 /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
618 * hardcoded into the shader. Update the shader to update the enabled clipplanes */
619 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
621 device->shader_backend->shader_select(context, use_ps(state), TRUE);
622 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
623 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
627 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
628 * of already set values
631 /* If enabling / disabling all
632 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
634 if (state->render_states[WINED3D_RS_CLIPPING])
636 enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
637 disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
639 else
641 disable = 0xffffffff;
642 enable = 0x00;
645 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
646 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
647 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
648 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
649 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
650 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
652 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
653 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
654 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
655 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
656 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
657 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
660 static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
662 const struct wined3d_gl_info *gl_info = context->gl_info;
663 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
664 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
665 * specular color. This is wrong:
666 * Separate specular color means the specular colour is maintained separately, whereas
667 * single color means it is merged in. However in both cases they are being used to
668 * some extent.
669 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
670 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
671 * running 1.4 yet!
674 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
675 * Instead, we need to setup the FinalCombiner properly.
677 * The default setup for the FinalCombiner is:
679 * <variable> <input> <mapping> <usage>
680 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
681 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
682 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
683 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
684 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
685 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
686 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
688 * That's pretty much fine as it is, except for variable B, which needs to take
689 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
690 * whether WINED3D_RS_SPECULARENABLE is enabled or not.
693 TRACE("Setting specular enable state and materials\n");
694 if (state->render_states[WINED3D_RS_SPECULARENABLE])
696 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
697 checkGLcall("glMaterialfv");
699 if (state->material.power > gl_info->limits.shininess)
701 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
702 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
703 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
704 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
705 * them, it should be safe to do so without major visual distortions.
707 WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
708 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
710 else
712 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
714 checkGLcall("glMaterialf(GL_SHININESS)");
716 if (gl_info->supported[EXT_SECONDARY_COLOR])
718 glEnable(GL_COLOR_SUM_EXT);
720 else
722 TRACE("Specular colors cannot be enabled in this version of opengl\n");
724 checkGLcall("glEnable(GL_COLOR_SUM)");
726 if (gl_info->supported[NV_REGISTER_COMBINERS])
728 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
729 checkGLcall("glFinalCombinerInputNV()");
731 } else {
732 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
734 /* for the case of enabled lighting: */
735 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
736 checkGLcall("glMaterialfv");
738 /* for the case of disabled lighting: */
739 if (gl_info->supported[EXT_SECONDARY_COLOR])
741 glDisable(GL_COLOR_SUM_EXT);
743 else
745 TRACE("Specular colors cannot be disabled in this version of opengl\n");
747 checkGLcall("glDisable(GL_COLOR_SUM)");
749 if (gl_info->supported[NV_REGISTER_COMBINERS])
751 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
752 checkGLcall("glFinalCombinerInputNV()");
756 TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
757 state->material.diffuse.r, state->material.diffuse.g,
758 state->material.diffuse.b, state->material.diffuse.a);
759 TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
760 state->material.ambient.r, state->material.ambient.g,
761 state->material.ambient.b, state->material.ambient.a);
762 TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
763 state->material.specular.r, state->material.specular.g,
764 state->material.specular.b, state->material.specular.a);
765 TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
766 state->material.emissive.r, state->material.emissive.g,
767 state->material.emissive.b, state->material.emissive.a);
769 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
770 checkGLcall("glMaterialfv(GL_AMBIENT)");
771 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
772 checkGLcall("glMaterialfv(GL_DIFFUSE)");
773 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
774 checkGLcall("glMaterialfv(GL_EMISSION)");
777 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
779 const struct wined3d_gl_info *gl_info = context->gl_info;
780 unsigned int i;
782 /* Note the texture color applies to all textures whereas
783 * GL_TEXTURE_ENV_COLOR applies to active only. */
784 float col[4];
785 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
787 /* And now the default texture color as well */
788 for (i = 0; i < gl_info->limits.texture_stages; ++i)
790 /* Note the WINED3D_RS value applies to all textures, but GL has one
791 * per texture, so apply it now ready to be used! */
792 context_active_texture(context, gl_info, i);
794 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
795 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
799 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
800 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
802 const struct wined3d_gl_info *gl_info = context->gl_info;
804 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
805 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
806 GL_EXTCALL(glActiveStencilFaceEXT(face));
807 checkGLcall("glActiveStencilFaceEXT(...)");
808 glStencilFunc(func, ref, mask);
809 checkGLcall("glStencilFunc(...)");
810 glStencilOp(stencilFail, depthFail, stencilPass);
811 checkGLcall("glStencilOp(...)");
814 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
816 switch (op)
818 case WINED3D_STENCIL_OP_KEEP:
819 return GL_KEEP;
820 case WINED3D_STENCIL_OP_ZERO:
821 return GL_ZERO;
822 case WINED3D_STENCIL_OP_REPLACE:
823 return GL_REPLACE;
824 case WINED3D_STENCIL_OP_INCR_SAT:
825 return GL_INCR;
826 case WINED3D_STENCIL_OP_DECR_SAT:
827 return GL_DECR;
828 case WINED3D_STENCIL_OP_INVERT:
829 return GL_INVERT;
830 case WINED3D_STENCIL_OP_INCR:
831 return GL_INCR_WRAP_EXT;
832 case WINED3D_STENCIL_OP_DECR:
833 return GL_DECR_WRAP_EXT;
834 default:
835 FIXME("Unrecognized stencil op %#x.\n", op);
836 return GL_KEEP;
840 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
842 const struct wined3d_gl_info *gl_info = context->gl_info;
843 DWORD onesided_enable = FALSE;
844 DWORD twosided_enable = FALSE;
845 GLint func = GL_ALWAYS;
846 GLint func_ccw = GL_ALWAYS;
847 GLint ref = 0;
848 GLuint mask = 0;
849 GLint stencilFail = GL_KEEP;
850 GLint depthFail = GL_KEEP;
851 GLint stencilPass = GL_KEEP;
852 GLint stencilFail_ccw = GL_KEEP;
853 GLint depthFail_ccw = GL_KEEP;
854 GLint stencilPass_ccw = GL_KEEP;
856 /* No stencil test without a stencil buffer. */
857 if (!state->fb->depth_stencil)
859 glDisable(GL_STENCIL_TEST);
860 checkGLcall("glDisable GL_STENCIL_TEST");
861 return;
864 onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
865 twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
866 if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
867 func = GL_ALWAYS;
868 if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
869 func_ccw = GL_ALWAYS;
870 ref = state->render_states[WINED3D_RS_STENCILREF];
871 mask = state->render_states[WINED3D_RS_STENCILMASK];
872 stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
873 depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
874 stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
875 stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
876 depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
877 stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
879 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
880 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
881 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
882 onesided_enable, twosided_enable, ref, mask,
883 func, stencilFail, depthFail, stencilPass,
884 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
886 if (twosided_enable && onesided_enable) {
887 glEnable(GL_STENCIL_TEST);
888 checkGLcall("glEnable GL_STENCIL_TEST");
890 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
892 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
893 * which has an effect on the code below too. If we apply the front face
894 * afterwards, we are sure that the active stencil face is set to front,
895 * and other stencil functions which do not use two sided stencil do not have
896 * to set it back
898 renderstate_stencil_twosided(context, GL_BACK,
899 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
900 renderstate_stencil_twosided(context, GL_FRONT,
901 func, ref, mask, stencilFail, depthFail, stencilPass);
903 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
905 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
906 checkGLcall("glStencilFuncSeparateATI(...)");
907 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
908 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
909 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
910 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
911 } else {
912 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
915 else if(onesided_enable)
917 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
919 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
920 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
923 /* This code disables the ATI extension as well, since the standard stencil functions are equal
924 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
926 glEnable(GL_STENCIL_TEST);
927 checkGLcall("glEnable GL_STENCIL_TEST");
928 glStencilFunc(func, ref, mask);
929 checkGLcall("glStencilFunc(...)");
930 glStencilOp(stencilFail, depthFail, stencilPass);
931 checkGLcall("glStencilOp(...)");
932 } else {
933 glDisable(GL_STENCIL_TEST);
934 checkGLcall("glDisable GL_STENCIL_TEST");
938 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
940 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
941 const struct wined3d_gl_info *gl_info = context->gl_info;
943 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
944 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
945 glStencilMask(mask);
946 checkGLcall("glStencilMask");
947 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
948 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
949 glStencilMask(mask);
952 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
954 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
956 glStencilMask(mask);
957 checkGLcall("glStencilMask");
960 static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
963 const struct wined3d_gl_info *gl_info = context->gl_info;
964 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
966 if (!state->render_states[WINED3D_RS_FOGENABLE])
967 return;
969 /* Table fog on: Never use fog coords, and use per-fragment fog */
970 if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
972 glHint(GL_FOG_HINT, GL_NICEST);
973 if(context->fog_coord) {
974 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
975 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
976 context->fog_coord = FALSE;
979 /* Range fog is only used with per-vertex fog in d3d */
980 if (gl_info->supported[NV_FOG_DISTANCE])
982 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
983 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
985 return;
988 /* Otherwise use per-vertex fog in any case */
989 glHint(GL_FOG_HINT, GL_FASTEST);
991 if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
993 /* No fog at all, or transformed vertices: Use fog coord */
994 if(!context->fog_coord) {
995 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
996 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
997 context->fog_coord = TRUE;
1000 else
1002 /* Otherwise, use the fragment depth */
1003 if(context->fog_coord) {
1004 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1005 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1006 context->fog_coord = FALSE;
1009 if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
1011 if (gl_info->supported[NV_FOG_DISTANCE])
1013 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1014 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1016 else
1018 WARN("Range fog enabled, but not supported by this GL implementation.\n");
1021 else if (gl_info->supported[NV_FOG_DISTANCE])
1023 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1024 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1029 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1031 float fogstart, fogend;
1032 union {
1033 DWORD d;
1034 float f;
1035 } tmpvalue;
1037 switch(context->fog_source) {
1038 case FOGSOURCE_VS:
1039 fogstart = 1.0f;
1040 fogend = 0.0f;
1041 break;
1043 case FOGSOURCE_COORD:
1044 fogstart = 255.0f;
1045 fogend = 0.0f;
1046 break;
1048 case FOGSOURCE_FFP:
1049 tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
1050 fogstart = tmpvalue.f;
1051 tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
1052 fogend = tmpvalue.f;
1053 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
1054 if(fogstart == fogend) {
1055 fogstart = -1.0f / 0.0f;
1056 fogend = 0.0f;
1058 break;
1060 default:
1061 /* This should not happen.context->fog_source is set in wined3d, not the app.
1062 * Still this is needed to make the compiler happy
1064 ERR("Unexpected fog coordinate source\n");
1065 fogstart = 0.0f;
1066 fogend = 0.0f;
1069 glFogf(GL_FOG_START, fogstart);
1070 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1071 TRACE("Fog Start == %f\n", fogstart);
1073 glFogf(GL_FOG_END, fogend);
1074 checkGLcall("glFogf(GL_FOG_END, fogend)");
1075 TRACE("Fog End == %f\n", fogend);
1078 void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1080 enum fogsource new_source;
1082 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
1084 if (!state->render_states[WINED3D_RS_FOGENABLE])
1086 /* No fog? Disable it, and we're done :-) */
1087 glDisableWINE(GL_FOG);
1088 checkGLcall("glDisable GL_FOG");
1089 return;
1092 /* Fog Rules:
1094 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1095 * It can use the Z value of the vertex, or the alpha component of the specular color.
1096 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1097 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1098 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1100 * FOGTABLEMODE != NONE:
1101 * The Z value is used, with the equation specified, no matter what vertex type.
1103 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1104 * Per vertex fog is calculated using the specified fog equation and the parameters
1106 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1107 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1108 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1111 * Rules for vertex fog with shaders:
1113 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1114 * the fog computation to happen during transformation while openGL expects it to happen
1115 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1116 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1117 * To solve this problem, WineD3D does:
1118 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1119 * shader,
1120 * and 2) disables the fog computation (in either the fixed function or programmable
1121 * rasterizer) if using a vertex program.
1123 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1124 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1125 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1126 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1127 * There are some GL differences between specular fog coords and vertex shaders though.
1129 * With table fog the vertex shader fog coordinate is ignored.
1131 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1132 * without shaders).
1135 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1136 * the system will apply only pixel(=table) fog effects."
1138 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
1140 if (use_vs(state))
1142 glFogi(GL_FOG_MODE, GL_LINEAR);
1143 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1144 new_source = FOGSOURCE_VS;
1146 else
1148 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
1150 /* If processed vertices are used, fall through to the NONE case */
1151 case WINED3D_FOG_EXP:
1152 if (!context->last_was_rhw)
1154 glFogi(GL_FOG_MODE, GL_EXP);
1155 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1156 new_source = FOGSOURCE_FFP;
1157 break;
1159 /* drop through */
1161 case WINED3D_FOG_EXP2:
1162 if (!context->last_was_rhw)
1164 glFogi(GL_FOG_MODE, GL_EXP2);
1165 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1166 new_source = FOGSOURCE_FFP;
1167 break;
1169 /* drop through */
1171 case WINED3D_FOG_LINEAR:
1172 if (!context->last_was_rhw)
1174 glFogi(GL_FOG_MODE, GL_LINEAR);
1175 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1176 new_source = FOGSOURCE_FFP;
1177 break;
1179 /* drop through */
1181 case WINED3D_FOG_NONE:
1182 /* Both are none? According to msdn the alpha channel of the specular
1183 * color contains a fog factor. Set it in drawStridedSlow.
1184 * Same happens with Vertexfog on transformed vertices
1186 new_source = FOGSOURCE_COORD;
1187 glFogi(GL_FOG_MODE, GL_LINEAR);
1188 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1189 break;
1191 default:
1192 FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
1193 state->render_states[WINED3D_RS_FOGVERTEXMODE]);
1194 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1197 } else {
1198 new_source = FOGSOURCE_FFP;
1200 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
1202 case WINED3D_FOG_EXP:
1203 glFogi(GL_FOG_MODE, GL_EXP);
1204 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1205 break;
1207 case WINED3D_FOG_EXP2:
1208 glFogi(GL_FOG_MODE, GL_EXP2);
1209 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1210 break;
1212 case WINED3D_FOG_LINEAR:
1213 glFogi(GL_FOG_MODE, GL_LINEAR);
1214 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1215 break;
1217 case WINED3D_FOG_NONE: /* Won't happen */
1218 default:
1219 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
1220 state->render_states[WINED3D_RS_FOGTABLEMODE]);
1224 glEnableWINE(GL_FOG);
1225 checkGLcall("glEnable GL_FOG");
1226 if (new_source != context->fog_source)
1228 context->fog_source = new_source;
1229 state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
1233 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1235 float col[4];
1237 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
1238 glFogfv(GL_FOG_COLOR, &col[0]);
1239 checkGLcall("glFog GL_FOG_COLOR");
1242 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1244 union {
1245 DWORD d;
1246 float f;
1247 } tmpvalue;
1249 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1250 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1251 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1254 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1256 const struct wined3d_device *device = context->swapchain->device;
1257 GLenum Parm = 0;
1259 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1260 * The vertex declaration will call this function if the fixed function pipeline is used.
1263 if(isStateDirty(context, STATE_VDECL)) {
1264 return;
1267 context->num_untracked_materials = 0;
1268 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1269 && state->render_states[WINED3D_RS_COLORVERTEX])
1271 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1272 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
1273 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
1274 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
1275 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
1277 if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1279 if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1280 Parm = GL_AMBIENT_AND_DIFFUSE;
1281 else
1282 Parm = GL_DIFFUSE;
1283 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1285 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1286 context->num_untracked_materials++;
1288 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1290 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1291 context->num_untracked_materials++;
1294 else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1296 Parm = GL_AMBIENT;
1297 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1299 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1300 context->num_untracked_materials++;
1302 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1304 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1305 context->num_untracked_materials++;
1308 else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1310 Parm = GL_EMISSION;
1311 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1313 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1314 context->num_untracked_materials++;
1317 else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1319 Parm = GL_SPECULAR;
1323 /* Nothing changed, return. */
1324 if (Parm == context->tracking_parm) return;
1326 if(!Parm) {
1327 glDisable(GL_COLOR_MATERIAL);
1328 checkGLcall("glDisable GL_COLOR_MATERIAL");
1329 } else {
1330 glColorMaterial(GL_FRONT_AND_BACK, Parm);
1331 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1332 glEnable(GL_COLOR_MATERIAL);
1333 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1336 /* Apparently calls to glMaterialfv are ignored for properties we're
1337 * tracking with glColorMaterial, so apply those here. */
1338 switch (context->tracking_parm) {
1339 case GL_AMBIENT_AND_DIFFUSE:
1340 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1341 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1342 checkGLcall("glMaterialfv");
1343 break;
1345 case GL_DIFFUSE:
1346 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1347 checkGLcall("glMaterialfv");
1348 break;
1350 case GL_AMBIENT:
1351 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1352 checkGLcall("glMaterialfv");
1353 break;
1355 case GL_EMISSION:
1356 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
1357 checkGLcall("glMaterialfv");
1358 break;
1360 case GL_SPECULAR:
1361 /* Only change material color if specular is enabled, otherwise it is set to black */
1362 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1364 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
1365 checkGLcall("glMaterialfv");
1367 else
1369 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1370 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1371 checkGLcall("glMaterialfv");
1373 break;
1376 context->tracking_parm = Parm;
1379 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1381 union
1383 DWORD d;
1384 struct wined3d_line_pattern lp;
1385 } tmppattern;
1386 tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
1388 TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1390 if (tmppattern.lp.repeat_factor)
1392 glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1393 checkGLcall("glLineStipple(repeat, linepattern)");
1394 glEnable(GL_LINE_STIPPLE);
1395 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1397 else
1399 glDisable(GL_LINE_STIPPLE);
1400 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1404 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1406 if (isStateDirty(context, STATE_VDECL))
1407 return;
1409 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1410 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1411 * by zero and is not properly defined in opengl, so avoid it
1413 if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
1414 && (context->swapchain->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1416 glEnable(GL_NORMALIZE);
1417 checkGLcall("glEnable(GL_NORMALIZE);");
1419 else
1421 glDisable(GL_NORMALIZE);
1422 checkGLcall("glDisable(GL_NORMALIZE);");
1426 static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1428 union {
1429 DWORD d;
1430 float f;
1431 } tmpvalue;
1433 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1434 if (tmpvalue.f != 1.0f)
1436 FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1438 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1439 if (tmpvalue.f != 64.0f)
1441 FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1446 static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1448 const struct wined3d_gl_info *gl_info = context->gl_info;
1449 union
1451 DWORD d;
1452 float f;
1453 } min, max;
1455 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1456 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1458 /* Max point size trumps min point size */
1459 if(min.f > max.f) {
1460 min.f = max.f;
1463 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1464 checkGLcall("glPointParameterfEXT(...)");
1465 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1466 checkGLcall("glPointParameterfEXT(...)");
1469 static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1471 const struct wined3d_gl_info *gl_info = context->gl_info;
1472 union
1474 DWORD d;
1475 float f;
1476 } min, max;
1478 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1479 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1481 /* Max point size trumps min point size */
1482 if(min.f > max.f) {
1483 min.f = max.f;
1486 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1487 checkGLcall("glPointParameterfARB(...)");
1488 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1489 checkGLcall("glPointParameterfARB(...)");
1492 static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1494 const struct wined3d_gl_info *gl_info = context->gl_info;
1495 /* TODO: Group this with the viewport */
1497 * POINTSCALEENABLE controls how point size value is treated. If set to
1498 * true, the point size is scaled with respect to height of viewport.
1499 * When set to false point size is in pixels.
1502 /* Default values */
1503 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1504 union {
1505 DWORD d;
1506 float f;
1507 } pointSize, A, B, C;
1509 pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
1510 A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
1511 B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
1512 C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
1514 if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1516 DWORD h = state->viewport.height;
1517 GLfloat scaleFactor;
1519 if (pointSize.f < gl_info->limits.pointsize_min)
1521 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1522 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1523 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1524 * are less than 1.0f. scale_factor = 1.0f / point_size.
1526 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1527 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1528 * is 1.0, but then accepts points below that and draws too small points
1530 pointSize.f = gl_info->limits.pointsize_min;
1532 else if(pointSize.f > gl_info->limits.pointsize_max)
1534 /* gl already scales the input to glPointSize,
1535 * d3d scales the result after the point size scale.
1536 * If the point size is bigger than the max size, use the
1537 * scaling to scale it bigger, and set the gl point size to max
1539 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1540 TRACE("scale: %f\n", scaleFactor);
1541 pointSize.f = gl_info->limits.pointsize_max;
1542 } else {
1543 scaleFactor = 1.0f;
1545 scaleFactor = powf(h * scaleFactor, 2);
1547 att[0] = A.f / scaleFactor;
1548 att[1] = B.f / scaleFactor;
1549 att[2] = C.f / scaleFactor;
1552 if (gl_info->supported[ARB_POINT_PARAMETERS])
1554 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1555 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1557 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1559 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1560 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1562 else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1564 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1567 glPointSize(pointSize.f);
1568 checkGLcall("glPointSize(...);");
1571 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1573 WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
1576 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1578 DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
1579 DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
1580 DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
1581 DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
1583 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1584 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1585 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1586 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1587 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1588 glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1589 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1590 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1591 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1592 checkGLcall("glColorMask(...)");
1594 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1595 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1597 FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1598 mask0, mask1, mask2, mask3);
1599 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1603 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1605 GL_EXTCALL(glColorMaskIndexedEXT(index,
1606 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1607 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1608 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1609 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1612 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1614 set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
1617 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1619 set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
1622 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1624 set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
1627 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1629 set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
1632 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1634 if (state->render_states[WINED3D_RS_LOCALVIEWER])
1636 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1637 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1638 } else {
1639 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1640 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1644 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1646 if (state->render_states[WINED3D_RS_LASTPIXEL])
1648 TRACE("Last Pixel Drawing Enabled\n");
1650 else
1652 static BOOL warned;
1653 if (!warned) {
1654 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1655 warned = TRUE;
1656 } else {
1657 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1662 static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1664 static BOOL warned;
1666 /* TODO: NV_POINT_SPRITE */
1667 if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1669 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1670 FIXME("Point sprites not supported\n");
1671 warned = TRUE;
1675 static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1677 if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1679 glEnable(GL_POINT_SPRITE_ARB);
1680 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1681 } else {
1682 glDisable(GL_POINT_SPRITE_ARB);
1683 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1687 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1689 if (state->render_states[WINED3D_RS_WRAP0]
1690 || state->render_states[WINED3D_RS_WRAP1]
1691 || state->render_states[WINED3D_RS_WRAP2]
1692 || state->render_states[WINED3D_RS_WRAP3]
1693 || state->render_states[WINED3D_RS_WRAP4]
1694 || state->render_states[WINED3D_RS_WRAP5]
1695 || state->render_states[WINED3D_RS_WRAP6]
1696 || state->render_states[WINED3D_RS_WRAP7]
1697 || state->render_states[WINED3D_RS_WRAP8]
1698 || state->render_states[WINED3D_RS_WRAP9]
1699 || state->render_states[WINED3D_RS_WRAP10]
1700 || state->render_states[WINED3D_RS_WRAP11]
1701 || state->render_states[WINED3D_RS_WRAP12]
1702 || state->render_states[WINED3D_RS_WRAP13]
1703 || state->render_states[WINED3D_RS_WRAP14]
1704 || state->render_states[WINED3D_RS_WRAP15])
1705 FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
1708 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1710 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1711 WARN("Multisample antialiasing not supported by GL.\n");
1714 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1716 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1718 glEnable(GL_MULTISAMPLE_ARB);
1719 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1720 } else {
1721 glDisable(GL_MULTISAMPLE_ARB);
1722 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1726 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1728 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
1730 glEnable(GL_SCISSOR_TEST);
1731 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1732 } else {
1733 glDisable(GL_SCISSOR_TEST);
1734 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1738 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1739 * OpenGL the bias is specified in units of "the smallest value that is
1740 * guaranteed to produce a resolvable offset for a given implementation". To
1741 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1742 * There's no practical way to retrieve that value from a given GL
1743 * implementation, but the D3D application has essentially the same problem,
1744 * which makes a guess of the depth buffer format's highest possible value a
1745 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1746 * depth slope, and doesn't need to be scaled. */
1747 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1749 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
1750 || state->render_states[WINED3D_RS_DEPTHBIAS])
1752 const struct wined3d_surface *depth = state->fb->depth_stencil;
1753 float scale;
1755 union
1757 DWORD d;
1758 float f;
1759 } scale_bias, const_bias;
1761 scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
1762 const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
1764 glEnable(GL_POLYGON_OFFSET_FILL);
1765 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1767 if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
1769 float bias = -(float)const_bias.d;
1770 glPolygonOffset(bias, bias);
1771 checkGLcall("glPolygonOffset");
1773 else
1775 if (depth)
1777 const struct wined3d_format *fmt = depth->resource.format;
1778 scale = powf(2, fmt->depth_size) - 1;
1779 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
1780 debug_d3dformat(fmt->id), scale);
1782 else
1784 /* The context manager will reapply this state on a depth stencil change */
1785 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
1786 scale = 0.0f;
1789 glPolygonOffset(scale_bias.f, const_bias.f * scale);
1790 checkGLcall("glPolygonOffset(...)");
1793 else
1795 glDisable(GL_POLYGON_OFFSET_FILL);
1796 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1800 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1802 if (state->render_states[WINED3D_RS_ZVISIBLE])
1803 FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
1806 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1808 if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
1810 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1811 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1812 } else {
1813 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1814 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1818 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1820 if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
1821 FIXME("Stippled Alpha not supported yet.\n");
1824 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1826 if (state->render_states[WINED3D_RS_ANTIALIAS])
1827 FIXME("Antialias not supported yet.\n");
1830 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1832 if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
1833 FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
1834 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
1837 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1839 if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
1840 FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
1841 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
1844 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1846 union {
1847 DWORD d;
1848 float f;
1849 } tmpvalue;
1850 tmpvalue.f = 1.0f;
1852 if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
1854 static BOOL displayed = FALSE;
1856 tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
1857 if(!displayed)
1858 FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1860 displayed = TRUE;
1864 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1866 if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
1867 FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
1868 state->render_states[WINED3D_RS_POSITIONDEGREE]);
1871 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1873 if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
1874 FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
1875 state->render_states[WINED3D_RS_NORMALDEGREE]);
1878 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1880 if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
1881 FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1882 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
1885 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1887 union {
1888 DWORD d;
1889 float f;
1890 } zmin, zmax;
1892 const struct wined3d_gl_info *gl_info = context->gl_info;
1894 if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1896 zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
1897 zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
1899 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1900 * In d3d9 test is not performed in this case*/
1901 if (zmin.f <= zmax.f)
1903 glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1904 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1905 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1906 checkGLcall("glDepthBoundsEXT(...)");
1908 else {
1909 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1910 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1913 else {
1914 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1915 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1918 state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
1921 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1923 if (state->render_states[WINED3D_RS_WRAPU])
1924 FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
1927 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1929 if (state->render_states[WINED3D_RS_WRAPV])
1930 FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
1933 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1935 if (state->render_states[WINED3D_RS_MONOENABLE])
1936 FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
1939 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1941 if (state->render_states[WINED3D_RS_ROP2])
1942 FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
1945 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1947 if (state->render_states[WINED3D_RS_PLANEMASK])
1948 FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
1951 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1953 if (state->render_states[WINED3D_RS_SUBPIXEL])
1954 FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
1957 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1959 if (state->render_states[WINED3D_RS_SUBPIXELX])
1960 FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
1963 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1965 if (state->render_states[WINED3D_RS_STIPPLEENABLE])
1966 FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
1969 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1971 if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
1972 FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
1975 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1977 if (state->render_states[WINED3D_RS_ANISOTROPY])
1978 FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
1981 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1983 if (state->render_states[WINED3D_RS_FLUSHBATCH])
1984 FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
1987 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1989 if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
1990 FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
1993 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1995 if (state->render_states[WINED3D_RS_EXTENTS])
1996 FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
1999 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2001 if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
2002 FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
2005 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2007 if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
2008 FIXME("Software vertex processing not implemented.\n");
2011 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2012 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2013 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2014 * flag specifies the complement of the input should be used. */
2015 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2016 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2018 /* Calculate the operand */
2019 if (complement) {
2020 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2021 else *operand = GL_ONE_MINUS_SRC_COLOR;
2022 } else {
2023 if (from_alpha) *operand = GL_SRC_ALPHA;
2024 else *operand = GL_SRC_COLOR;
2027 /* Calculate the source */
2028 switch (arg & WINED3DTA_SELECTMASK) {
2029 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2030 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2031 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2032 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2033 case WINED3DTA_SPECULAR:
2035 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2036 * 'Secondary color' and isn't supported until base GL supports it
2037 * There is no concept of temp registers as far as I can tell
2039 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2040 *source = GL_TEXTURE;
2041 break;
2042 default:
2043 FIXME("Unrecognized texture arg %#x\n", arg);
2044 *source = GL_TEXTURE;
2045 break;
2049 /* Setup the texture operations texture stage states */
2050 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2051 BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2053 GLenum src1, src2, src3;
2054 GLenum opr1, opr2, opr3;
2055 GLenum comb_target;
2056 GLenum src0_target, src1_target, src2_target;
2057 GLenum opr0_target, opr1_target, opr2_target;
2058 GLenum scal_target;
2059 GLenum opr=0, invopr, src3_target, opr3_target;
2060 BOOL Handled = FALSE;
2062 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2064 /* This is called by a state handler which has the gl lock held and a context for the thread */
2066 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2067 the form (a1 <operation> a2). However, some of the more complex operations
2068 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2069 in a third parameter called a0. Therefore these are operations of the form
2070 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2072 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2073 functions below, expect their syntax to differ slightly to those listed in the
2074 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2075 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2077 if (isAlpha)
2079 comb_target = GL_COMBINE_ALPHA;
2080 src0_target = GL_SOURCE0_ALPHA;
2081 src1_target = GL_SOURCE1_ALPHA;
2082 src2_target = GL_SOURCE2_ALPHA;
2083 opr0_target = GL_OPERAND0_ALPHA;
2084 opr1_target = GL_OPERAND1_ALPHA;
2085 opr2_target = GL_OPERAND2_ALPHA;
2086 scal_target = GL_ALPHA_SCALE;
2088 else
2090 comb_target = GL_COMBINE_RGB;
2091 src0_target = GL_SOURCE0_RGB;
2092 src1_target = GL_SOURCE1_RGB;
2093 src2_target = GL_SOURCE2_RGB;
2094 opr0_target = GL_OPERAND0_RGB;
2095 opr1_target = GL_OPERAND1_RGB;
2096 opr2_target = GL_OPERAND2_RGB;
2097 scal_target = GL_RGB_SCALE;
2100 /* If a texture stage references an invalid texture unit the stage just
2101 * passes through the result from the previous stage */
2102 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2104 arg1 = WINED3DTA_CURRENT;
2105 op = WINED3D_TOP_SELECT_ARG1;
2108 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2110 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2111 } else {
2112 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2114 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2115 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2117 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2119 Handled = TRUE; /* Assume will be handled */
2121 /* Other texture operations require special extensions: */
2122 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2124 if (isAlpha) {
2125 opr = GL_SRC_ALPHA;
2126 invopr = GL_ONE_MINUS_SRC_ALPHA;
2127 src3_target = GL_SOURCE3_ALPHA_NV;
2128 opr3_target = GL_OPERAND3_ALPHA_NV;
2129 } else {
2130 opr = GL_SRC_COLOR;
2131 invopr = GL_ONE_MINUS_SRC_COLOR;
2132 src3_target = GL_SOURCE3_RGB_NV;
2133 opr3_target = GL_OPERAND3_RGB_NV;
2135 switch (op)
2137 case WINED3D_TOP_DISABLE: /* Only for alpha */
2138 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2139 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2140 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2141 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2142 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2143 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2144 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2145 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2146 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2147 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2148 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2149 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2150 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2151 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2152 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2153 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2154 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2155 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2156 break;
2157 case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
2158 case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
2159 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2160 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2161 if (op == WINED3D_TOP_SELECT_ARG1)
2163 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2164 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2165 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2166 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2167 } else {
2168 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2169 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2170 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2171 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2173 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2174 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2175 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2176 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2177 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2178 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2179 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2180 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2181 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2182 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2183 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2184 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2185 break;
2187 case WINED3D_TOP_MODULATE:
2188 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2189 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2190 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2191 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2192 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2193 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2194 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2195 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2196 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2197 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2198 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2199 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2200 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2201 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2202 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2203 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2204 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2205 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2206 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2207 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2208 break;
2209 case WINED3D_TOP_MODULATE_2X:
2210 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2211 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2212 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2213 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2214 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2215 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2216 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2217 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2218 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2219 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2220 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2221 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2222 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2223 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2224 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2225 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2226 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2227 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2228 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2229 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2230 break;
2231 case WINED3D_TOP_MODULATE_4X:
2232 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2233 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2234 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2235 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2236 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2237 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2238 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2239 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2240 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2241 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2242 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2243 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2244 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2245 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2246 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2247 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2248 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2249 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2250 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2251 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2252 break;
2254 case WINED3D_TOP_ADD:
2255 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2256 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2257 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2258 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2259 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2260 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2261 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2262 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2263 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2264 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2265 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2266 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2267 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2268 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2269 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2270 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2271 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2272 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2273 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2274 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2275 break;
2277 case WINED3D_TOP_ADD_SIGNED:
2278 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2279 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2280 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2281 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2282 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2283 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2284 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2285 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2286 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2287 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2288 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2289 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2290 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2291 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2292 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2293 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2294 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2295 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2296 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2297 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2298 break;
2300 case WINED3D_TOP_ADD_SIGNED_2X:
2301 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2302 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2303 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2304 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2305 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2306 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2307 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2308 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2309 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2310 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2311 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2312 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2313 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2314 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2315 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2316 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2317 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2318 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2319 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2320 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2321 break;
2323 case WINED3D_TOP_ADD_SMOOTH:
2324 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2325 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2326 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2327 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2328 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2329 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2330 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2331 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2332 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2333 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2334 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2335 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2336 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2337 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2338 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2339 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2340 switch (opr1) {
2341 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2342 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2343 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2344 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2346 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2347 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2348 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2349 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2350 break;
2352 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2353 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2354 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2355 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2356 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2357 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2358 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2359 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
2360 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
2361 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2362 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2363 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2364 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2365 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2366 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2367 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
2368 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
2369 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2370 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2371 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2372 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2373 break;
2374 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2375 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2376 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2377 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2378 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2379 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2380 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2381 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2382 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2383 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2384 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2385 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2386 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2387 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2388 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2389 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2390 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2391 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2392 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2393 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2394 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2395 break;
2396 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2397 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2398 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2399 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2400 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2401 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2402 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2403 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
2404 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
2405 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2406 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2407 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2408 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2409 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2410 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2411 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
2412 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
2413 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2414 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2415 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2416 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2417 break;
2418 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2419 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2420 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2421 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2422 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2423 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2424 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2425 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2426 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2427 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2428 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2429 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2430 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2431 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2432 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2433 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2434 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2435 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2436 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2437 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2438 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2439 break;
2440 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2441 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2442 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2443 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2444 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2445 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2446 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2447 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2448 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2449 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2450 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2451 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2452 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2453 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2454 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2455 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2456 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2457 switch (opr) {
2458 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2459 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2461 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2462 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2463 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2464 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2465 break;
2466 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2467 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2468 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2469 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2470 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2471 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2472 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2473 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2474 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2475 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2476 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2477 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2478 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2479 switch (opr1) {
2480 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2481 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2483 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2484 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2485 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2486 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2487 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2488 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2489 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2490 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2491 break;
2492 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2493 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2494 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2495 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2496 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2497 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2498 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2499 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2500 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2501 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2502 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2503 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2504 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2505 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2506 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2507 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2508 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2509 switch (opr1) {
2510 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2511 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2512 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2513 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2515 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2516 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2517 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2518 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2519 break;
2520 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2521 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2522 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2523 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2524 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2525 switch (opr1) {
2526 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2527 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2528 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2529 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2531 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2532 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2533 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2534 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2535 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2536 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2537 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2538 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2539 switch (opr1) {
2540 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2541 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2543 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2544 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2545 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2546 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2547 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2548 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2549 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2550 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2551 break;
2552 case WINED3D_TOP_MULTIPLY_ADD:
2553 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2554 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2555 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2556 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2557 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2558 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2559 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2560 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2561 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2562 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2563 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2564 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2565 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2566 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2567 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2568 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2569 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2570 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2571 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2572 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2573 break;
2575 case WINED3D_TOP_BUMPENVMAP:
2576 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
2577 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2579 default:
2580 Handled = FALSE;
2582 if (Handled) {
2583 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2584 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2586 return;
2588 } /* GL_NV_texture_env_combine4 */
2590 Handled = TRUE; /* Again, assume handled */
2591 switch (op) {
2592 case WINED3D_TOP_DISABLE: /* Only for alpha */
2593 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2594 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2595 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2596 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2597 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2598 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2599 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2600 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2601 break;
2602 case WINED3D_TOP_SELECT_ARG1:
2603 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2604 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2605 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2606 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2607 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2608 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2609 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2610 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2611 break;
2612 case WINED3D_TOP_SELECT_ARG2:
2613 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2614 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2615 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2616 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2617 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2618 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2619 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2620 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2621 break;
2622 case WINED3D_TOP_MODULATE:
2623 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2624 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2625 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2626 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2627 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2628 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2629 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2630 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2631 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2632 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2633 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2634 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2635 break;
2636 case WINED3D_TOP_MODULATE_2X:
2637 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2638 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2639 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2640 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2641 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2642 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2643 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2644 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2645 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2646 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2647 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2648 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2649 break;
2650 case WINED3D_TOP_MODULATE_4X:
2651 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2652 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2653 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2654 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2655 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2656 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2657 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2658 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2659 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2660 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2661 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2662 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2663 break;
2664 case WINED3D_TOP_ADD:
2665 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2666 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2667 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2668 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2669 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2670 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2671 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2672 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2673 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2674 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2675 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2676 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2677 break;
2678 case WINED3D_TOP_ADD_SIGNED:
2679 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2680 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2681 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2682 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2683 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2684 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2685 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2686 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2687 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2688 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2689 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2690 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2691 break;
2692 case WINED3D_TOP_ADD_SIGNED_2X:
2693 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2694 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2695 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2696 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2697 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2698 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2699 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2700 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2701 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2702 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2703 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2704 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2705 break;
2706 case WINED3D_TOP_SUBTRACT:
2707 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2709 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2710 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2711 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2712 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2713 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2714 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2715 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2716 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2717 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2718 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2719 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2720 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2721 } else {
2722 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2724 break;
2726 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2727 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2728 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2729 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2730 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2731 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2732 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2733 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2734 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2735 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2736 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2737 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
2738 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2739 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2740 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2741 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2742 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2743 break;
2744 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2745 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2746 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2747 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2748 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2749 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2750 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2751 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2752 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2753 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2754 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2755 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2756 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2757 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2758 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2759 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2760 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2761 break;
2762 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2763 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2764 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2765 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2766 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2767 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2768 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2769 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2770 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2771 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2772 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2773 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
2774 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2775 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2776 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2777 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2778 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2779 break;
2780 case WINED3D_TOP_BLEND_CURRENT_ALPHA:
2781 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2782 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2783 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2784 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2785 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2786 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2787 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2788 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2789 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2790 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2791 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
2792 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2793 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2794 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2795 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2796 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2797 break;
2798 case WINED3D_TOP_DOTPRODUCT3:
2799 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2801 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2802 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2804 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2806 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2807 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2808 } else {
2809 FIXME("This version of opengl does not support GL_DOT3\n");
2811 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2812 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2813 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2814 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2815 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2816 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2817 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2818 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2819 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2820 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2821 break;
2822 case WINED3D_TOP_LERP:
2823 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2824 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2825 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2826 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2827 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2828 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2829 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2830 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2831 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2832 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2833 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2834 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2835 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2836 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2837 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2838 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2839 break;
2840 case WINED3D_TOP_ADD_SMOOTH:
2841 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2843 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2844 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2845 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2846 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2847 switch (opr1) {
2848 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2849 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2850 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2851 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2853 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2854 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2855 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2856 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2857 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2858 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2859 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2860 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2861 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2862 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2863 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2864 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2865 } else
2866 Handled = FALSE;
2867 break;
2868 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2869 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2871 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2872 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2873 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2874 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2875 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2876 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2877 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2878 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2879 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2880 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2881 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2882 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2883 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2884 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2885 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2886 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2887 } else
2888 Handled = FALSE;
2889 break;
2890 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2891 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2893 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2894 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2895 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2896 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2897 switch (opr1) {
2898 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2899 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2900 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2901 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2903 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2904 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2905 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2906 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2907 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2908 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2909 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2910 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2911 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2912 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2913 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2914 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2915 } else
2916 Handled = FALSE;
2917 break;
2918 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2919 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2921 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2922 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2923 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2924 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2925 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2926 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2927 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2928 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2929 switch (opr1) {
2930 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2931 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2932 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2933 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2935 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2936 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2937 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2938 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2939 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2940 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2941 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2942 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2943 } else
2944 Handled = FALSE;
2945 break;
2946 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2947 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2949 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2950 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2951 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2952 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2953 switch (opr1) {
2954 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2955 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2956 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2957 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2959 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2960 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2961 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2962 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2963 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2964 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2965 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2966 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2967 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2968 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2969 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2970 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2971 } else
2972 Handled = FALSE;
2973 break;
2974 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2975 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2977 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2978 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2979 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2980 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2981 switch (opr1) {
2982 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2983 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2984 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2985 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2987 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2988 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2989 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2990 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2991 switch (opr1) {
2992 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2993 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2994 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2995 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2997 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2998 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2999 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3000 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3001 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3002 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3003 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3004 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3005 } else
3006 Handled = FALSE;
3007 break;
3008 case WINED3D_TOP_MULTIPLY_ADD:
3009 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3011 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3012 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3013 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3014 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3015 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3016 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3017 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3018 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3019 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3020 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3021 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3022 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3023 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3024 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3025 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3026 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3027 } else
3028 Handled = FALSE;
3029 break;
3030 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3031 case WINED3D_TOP_BUMPENVMAP:
3032 if (gl_info->supported[NV_TEXTURE_SHADER2])
3034 /* Technically texture shader support without register combiners is possible, but not expected to occur
3035 * on real world cards, so for now a fixme should be enough
3037 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3039 default:
3040 Handled = FALSE;
3043 if (Handled) {
3044 BOOL combineOK = TRUE;
3045 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3047 DWORD op2;
3049 if (isAlpha)
3050 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3051 else
3052 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3054 /* Note: If COMBINE4 in effect can't go back to combine! */
3055 switch (op2)
3057 case WINED3D_TOP_ADD_SMOOTH:
3058 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3059 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3060 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3061 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3062 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3063 case WINED3D_TOP_MULTIPLY_ADD:
3064 /* Ignore those implemented in both cases */
3065 switch (op)
3067 case WINED3D_TOP_SELECT_ARG1:
3068 case WINED3D_TOP_SELECT_ARG2:
3069 combineOK = FALSE;
3070 Handled = FALSE;
3071 break;
3072 default:
3073 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3074 return;
3079 if (combineOK)
3081 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3082 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3084 return;
3088 /* After all the extensions, if still unhandled, report fixme */
3089 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3093 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3095 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3096 const struct wined3d_device *device = context->swapchain->device;
3097 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3098 DWORD mapped_stage = device->texUnitMap[stage];
3099 const struct wined3d_gl_info *gl_info = context->gl_info;
3101 TRACE("Setting color op for stage %d\n", stage);
3103 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3104 if (use_ps(state)) return;
3106 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3108 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3110 if (tex_used && mapped_stage >= gl_info->limits.textures)
3112 FIXME("Attempt to enable unsupported stage!\n");
3113 return;
3115 context_active_texture(context, gl_info, mapped_stage);
3118 if (stage >= state->lowest_disabled_stage)
3120 TRACE("Stage disabled\n");
3121 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3123 /* Disable everything here */
3124 glDisable(GL_TEXTURE_2D);
3125 checkGLcall("glDisable(GL_TEXTURE_2D)");
3126 glDisable(GL_TEXTURE_3D);
3127 checkGLcall("glDisable(GL_TEXTURE_3D)");
3128 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3130 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3131 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3133 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3135 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3136 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3139 /* All done */
3140 return;
3143 /* The sampler will also activate the correct texture dimensions, so no
3144 * need to do it here if the sampler for this stage is dirty. */
3145 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3146 texture_activate_dimensions(state->textures[stage], gl_info);
3148 set_tex_op(gl_info, state, FALSE, stage,
3149 state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3150 state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3151 state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3152 state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3155 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3157 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3158 const struct wined3d_device *device = context->swapchain->device;
3159 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3160 DWORD mapped_stage = device->texUnitMap[stage];
3161 const struct wined3d_gl_info *gl_info = context->gl_info;
3162 DWORD op, arg1, arg2, arg0;
3164 TRACE("Setting alpha op for stage %d\n", stage);
3165 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3166 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3168 if (tex_used && mapped_stage >= gl_info->limits.textures)
3170 FIXME("Attempt to enable unsupported stage!\n");
3171 return;
3173 context_active_texture(context, gl_info, mapped_stage);
3176 op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3177 arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3178 arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3179 arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3181 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3183 struct wined3d_texture *texture = state->textures[0];
3184 GLenum texture_dimensions = texture->target;
3186 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3188 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3190 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3192 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3193 * properly. On the other hand applications can still use texture combiners apparently. This code
3194 * takes care that apps cannot remove the texture's alpha channel entirely.
3196 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3197 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3198 * and alpha component of diffuse color to draw things like translucent text and perform other
3199 * blending effects.
3201 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3202 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3203 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3204 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3205 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3206 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3207 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3208 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3209 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3210 * alpha.
3212 * What to do with multitexturing? So far no app has been found that uses color keying with
3213 * multitexturing */
3214 if (op == WINED3D_TOP_DISABLE)
3216 arg1 = WINED3DTA_TEXTURE;
3217 op = WINED3D_TOP_SELECT_ARG1;
3219 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3221 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3223 arg2 = WINED3DTA_TEXTURE;
3224 op = WINED3D_TOP_MODULATE;
3226 else arg1 = WINED3DTA_TEXTURE;
3228 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3230 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3232 arg1 = WINED3DTA_TEXTURE;
3233 op = WINED3D_TOP_MODULATE;
3235 else arg2 = WINED3DTA_TEXTURE;
3241 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3242 * this if block here, and the other code(color keying, texture unit selection) are the same
3244 TRACE("Setting alpha op for stage %d\n", stage);
3245 if (gl_info->supported[NV_REGISTER_COMBINERS])
3247 set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3248 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3250 else
3252 set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3256 static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3258 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3259 const struct wined3d_device *device = context->swapchain->device;
3260 const struct wined3d_gl_info *gl_info = context->gl_info;
3261 DWORD mapped_stage = device->texUnitMap[texUnit];
3262 BOOL generated;
3263 int coordIdx;
3265 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3266 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3268 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3269 return;
3272 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3273 if (mapped_stage >= gl_info->limits.textures) return;
3275 context_active_texture(context, gl_info, mapped_stage);
3276 generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3277 coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3279 set_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3280 state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3281 generated, context->last_was_rhw,
3282 device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3283 ? device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3284 : WINED3DFMT_UNKNOWN,
3285 device->frag_pipe->ffp_proj_control);
3287 /* The sampler applying function calls us if this changes */
3288 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3290 if(generated) {
3291 FIXME("Non-power2 texture being used with generated texture coords\n");
3293 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3294 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3295 if (!use_ps(state))
3297 TRACE("Non power two matrix multiply fixup\n");
3298 glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3303 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3305 unsigned int texture_idx;
3307 for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3309 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3310 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3314 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3315 GLuint *curVBO, const struct wined3d_state *state)
3317 const struct wined3d_device *device = context->swapchain->device;
3318 const struct wined3d_gl_info *gl_info = context->gl_info;
3319 unsigned int mapped_stage = 0;
3320 unsigned int textureNo = 0;
3322 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3324 int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3326 mapped_stage = device->texUnitMap[textureNo];
3327 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3329 if (mapped_stage >= gl_info->limits.texture_coords)
3331 FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3332 continue;
3335 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3337 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3339 TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3340 textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3342 if (*curVBO != e->data.buffer_object)
3344 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3345 checkGLcall("glBindBufferARB");
3346 *curVBO = e->data.buffer_object;
3349 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3350 checkGLcall("glClientActiveTextureARB");
3352 /* The coords to supply depend completely on the fvf / vertex shader */
3353 glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3354 e->data.addr + state->load_base_vertex_index * e->stride);
3355 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3357 else
3359 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3362 if (gl_info->supported[NV_REGISTER_COMBINERS])
3364 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3365 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3367 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3371 checkGLcall("loadTexCoords");
3374 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3376 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3377 const struct wined3d_device *device = context->swapchain->device;
3378 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3379 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3380 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3381 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3382 const struct wined3d_gl_info *gl_info = context->gl_info;
3383 DWORD mapped_stage = device->texUnitMap[stage];
3385 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3387 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3388 return;
3391 if (mapped_stage >= gl_info->limits.fragment_samplers)
3393 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3394 return;
3396 context_active_texture(context, gl_info, mapped_stage);
3398 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3400 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3401 * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3402 * means use the vertex position (camera-space) as the input texture coordinates
3403 * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3404 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3405 * to the TEXCOORDINDEX value
3407 switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3409 case WINED3DTSS_TCI_PASSTHRU:
3410 /* Use the specified texture coordinates contained within the
3411 * vertex format. This value resolves to zero. */
3412 glDisable(GL_TEXTURE_GEN_S);
3413 glDisable(GL_TEXTURE_GEN_T);
3414 glDisable(GL_TEXTURE_GEN_R);
3415 glDisable(GL_TEXTURE_GEN_Q);
3416 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3417 break;
3419 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3420 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3421 * as the input texture coordinates for this stage's texture transformation. This
3422 * equates roughly to EYE_LINEAR */
3424 glMatrixMode(GL_MODELVIEW);
3425 glPushMatrix();
3426 glLoadIdentity();
3427 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3428 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3429 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3430 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3431 glPopMatrix();
3432 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3434 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3435 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3436 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3437 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3439 glEnable(GL_TEXTURE_GEN_S);
3440 glEnable(GL_TEXTURE_GEN_T);
3441 glEnable(GL_TEXTURE_GEN_R);
3442 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3444 break;
3446 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3447 /* Note that NV_TEXGEN_REFLECTION support is implied when
3448 * ARB_TEXTURE_CUBE_MAP is supported */
3449 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3451 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3452 break;
3455 glMatrixMode(GL_MODELVIEW);
3456 glPushMatrix();
3457 glLoadIdentity();
3458 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3459 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3460 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3461 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3462 glPopMatrix();
3463 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3465 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3466 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3467 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3468 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3470 glEnable(GL_TEXTURE_GEN_S);
3471 glEnable(GL_TEXTURE_GEN_T);
3472 glEnable(GL_TEXTURE_GEN_R);
3473 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3475 break;
3477 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3478 /* Note that NV_TEXGEN_REFLECTION support is implied when
3479 * ARB_TEXTURE_CUBE_MAP is supported */
3480 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3482 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3483 break;
3486 glMatrixMode(GL_MODELVIEW);
3487 glPushMatrix();
3488 glLoadIdentity();
3489 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3490 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3491 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3492 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3493 glPopMatrix();
3494 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3496 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3497 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3498 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3499 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3501 glEnable(GL_TEXTURE_GEN_S);
3502 glEnable(GL_TEXTURE_GEN_T);
3503 glEnable(GL_TEXTURE_GEN_R);
3504 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3506 break;
3508 case WINED3DTSS_TCI_SPHEREMAP:
3509 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3510 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3511 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3513 glEnable(GL_TEXTURE_GEN_S);
3514 glEnable(GL_TEXTURE_GEN_T);
3515 glDisable(GL_TEXTURE_GEN_R);
3516 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3518 break;
3520 default:
3521 FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3522 state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3523 glDisable(GL_TEXTURE_GEN_S);
3524 glDisable(GL_TEXTURE_GEN_T);
3525 glDisable(GL_TEXTURE_GEN_R);
3526 glDisable(GL_TEXTURE_GEN_Q);
3527 checkGLcall("Disable texgen.");
3529 break;
3532 /* Update the texture matrix. */
3533 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3534 transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3536 if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3538 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3539 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3540 * and do all the things linked to it
3541 * TODO: Tidy that up to reload only the arrays of the changed unit
3543 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3545 unload_tex_coords(gl_info);
3546 load_tex_coords(context, &device->strided_streams, &curVBO, state);
3550 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3552 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3553 const struct wined3d_shader *ps = state->pixel_shader;
3555 if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3557 /* The pixel shader has to know the luminance scale. Do a constants
3558 * update if it isn't scheduled anyway. */
3559 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3560 && !isStateDirty(context, STATE_PIXELSHADER))
3561 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3565 static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3567 const DWORD sampler = state_id - STATE_SAMPLER(0);
3568 const struct wined3d_texture *texture = state->textures[sampler];
3570 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3572 if(!texture) return;
3573 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3574 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3575 * scaling is reapplied or removed, the texture matrix has to be reapplied
3577 * The mapped stage is already active because the sampler() function below, which is part of the
3578 * misc pipeline
3580 if (sampler < MAX_TEXTURES)
3582 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3584 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3586 const struct wined3d_device *device = context->swapchain->device;
3588 if (texIsPow2)
3589 context->lastWasPow2Texture |= 1 << sampler;
3590 else
3591 context->lastWasPow2Texture &= ~(1 << sampler);
3593 transform_texture(context, state,
3594 STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3599 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3601 const struct wined3d_device *device = context->swapchain->device;
3602 DWORD sampler = state_id - STATE_SAMPLER(0);
3603 DWORD mapped_stage = device->texUnitMap[sampler];
3604 const struct wined3d_gl_info *gl_info = context->gl_info;
3605 union {
3606 float f;
3607 DWORD d;
3608 } tmpvalue;
3610 TRACE("Sampler: %d\n", sampler);
3611 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3612 * only has to bind textures and set the per texture states
3615 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3617 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3618 return;
3621 if (mapped_stage >= gl_info->limits.combined_samplers)
3623 return;
3625 context_active_texture(context, gl_info, mapped_stage);
3627 if (state->textures[sampler])
3629 struct wined3d_texture *texture = state->textures[sampler];
3630 BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3632 texture->texture_ops->texture_bind(texture, context, srgb);
3633 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3635 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3637 tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3638 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3639 GL_TEXTURE_LOD_BIAS_EXT,
3640 tmpvalue.f);
3641 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3644 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3646 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3648 /* If color keying is enabled update the alpha test, it
3649 * depends on the existence of a color key in stage 0. */
3650 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3654 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3655 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3656 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3658 else
3660 if (sampler < state->lowest_disabled_stage)
3662 /* TODO: What should I do with pixel shaders here ??? */
3663 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3665 /* If color keying is enabled update the alpha test, it
3666 * depends on the existence of a color key in stage 0. */
3667 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3669 } /* Otherwise tex_colorop disables the stage */
3670 context_bind_texture(context, GL_NONE, 0);
3674 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3676 const struct wined3d_device *device = context->swapchain->device;
3677 BOOL use_vshader = use_vs(state);
3678 BOOL use_pshader = use_ps(state);
3679 unsigned int i;
3681 if (use_pshader)
3683 if (!context->last_was_pshader)
3685 /* Former draw without a pixel shader, some samplers may be
3686 * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3687 * make sure to enable them. */
3688 for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3690 if (!isStateDirty(context, STATE_SAMPLER(i)))
3691 sampler(context, state, STATE_SAMPLER(i));
3693 context->last_was_pshader = TRUE;
3695 else
3697 /* Otherwise all samplers were activated by the code above in
3698 * earlier draws, or by sampler() if a different texture was
3699 * bound. I don't have to do anything. */
3702 else
3704 /* Disabled the pixel shader - color ops weren't applied while it was
3705 * enabled, so re-apply them. */
3706 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3708 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3709 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3711 context->last_was_pshader = FALSE;
3714 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
3716 device->shader_backend->shader_select(context, use_pshader, use_vshader);
3718 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader))
3719 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
3723 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3725 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3726 const struct wined3d_shader *ps = state->pixel_shader;
3728 if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3730 /* The pixel shader has to know the bump env matrix. Do a constants
3731 * update if it isn't scheduled anyway. */
3732 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3733 && !isStateDirty(context, STATE_PIXELSHADER))
3734 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3738 static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3740 /* This function is called by transform_view below if the view matrix was changed too
3742 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3743 * does not always update the world matrix, only on a switch between transformed
3744 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3745 * draw, but that should be rather rare and cheaper in total.
3747 glMatrixMode(GL_MODELVIEW);
3748 checkGLcall("glMatrixMode");
3750 if(context->last_was_rhw) {
3751 glLoadIdentity();
3752 checkGLcall("glLoadIdentity()");
3754 else
3756 /* In the general case, the view matrix is the identity matrix */
3757 if (context->swapchain->device->view_ident)
3759 glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3760 checkGLcall("glLoadMatrixf");
3762 else
3764 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3765 checkGLcall("glLoadMatrixf");
3766 glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3767 checkGLcall("glMultMatrixf");
3772 static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3774 UINT index = state_id - STATE_CLIPPLANE(0);
3776 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= context->gl_info->limits.clipplanes)
3777 return;
3779 glMatrixMode(GL_MODELVIEW);
3780 glPushMatrix();
3782 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3783 if (!use_vs(state))
3784 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3785 else
3786 /* with vertex shaders, clip planes are not transformed in direct3d,
3787 * in OpenGL they are still transformed by the model view.
3789 glLoadIdentity();
3791 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3792 state->clip_planes[index][0],
3793 state->clip_planes[index][1],
3794 state->clip_planes[index][2],
3795 state->clip_planes[index][3]);
3796 glClipPlane(GL_CLIP_PLANE0 + index, state->clip_planes[index]);
3797 checkGLcall("glClipPlane");
3799 glPopMatrix();
3802 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3804 UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3805 GLenum glMat;
3806 TRACE("Setting world matrix %d\n", matrix);
3808 if (matrix >= context->gl_info->limits.blends)
3810 WARN("Unsupported blend matrix set\n");
3811 return;
3814 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3815 return;
3817 /* GL_MODELVIEW0_ARB: 0x1700
3818 * GL_MODELVIEW1_ARB: 0x850a
3819 * GL_MODELVIEW2_ARB: 0x8722
3820 * GL_MODELVIEW3_ARB: 0x8723
3821 * etc
3822 * GL_MODELVIEW31_ARB: 0x873F
3824 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3825 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3827 glMatrixMode(glMat);
3828 checkGLcall("glMatrixMode(glMat)");
3830 /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3831 * matrices while gl uses only 2. To avoid weighting the view matrix
3832 * incorrectly it has to be multiplied into every GL modelview matrix. */
3833 if (context->swapchain->device->view_ident)
3835 glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3836 checkGLcall("glLoadMatrixf");
3838 else
3840 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3841 checkGLcall("glLoadMatrixf");
3842 glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3843 checkGLcall("glMultMatrixf");
3847 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3849 enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3850 static unsigned int once;
3852 if (f == WINED3D_VBF_DISABLE)
3853 return;
3855 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3856 else WARN("Vertex blend flags %#x not supported.\n", f);
3859 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3861 enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3862 struct wined3d_device *device = context->swapchain->device;
3863 const struct wined3d_gl_info *gl_info = context->gl_info;
3864 static unsigned int once;
3866 switch (val)
3868 case WINED3D_VBF_1WEIGHTS:
3869 case WINED3D_VBF_2WEIGHTS:
3870 case WINED3D_VBF_3WEIGHTS:
3871 glEnable(GL_VERTEX_BLEND_ARB);
3872 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3874 /* D3D adds one more matrix which has weight (1 - sum(weights)).
3875 * This is enabled at context creation with enabling
3876 * GL_WEIGHT_SUM_UNITY_ARB. */
3877 GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3879 if (!device->vertexBlendUsed)
3881 unsigned int i;
3882 for (i = 1; i < gl_info->limits.blends; ++i)
3884 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3885 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3887 device->vertexBlendUsed = TRUE;
3889 break;
3891 case WINED3D_VBF_TWEENING:
3892 case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3893 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3894 else WARN("Vertex blend flags %#x not supported.\n", val);
3895 /* Fall through. */
3896 case WINED3D_VBF_DISABLE:
3897 glDisable(GL_VERTEX_BLEND_ARB);
3898 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3899 break;
3903 static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3905 const struct wined3d_gl_info *gl_info = context->gl_info;
3906 const struct wined3d_light_info *light = NULL;
3907 unsigned int k;
3909 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3910 * NOTE: We have to reset the positions even if the light/plane is not currently
3911 * enabled, since the call to enable it will not reset the position.
3912 * NOTE2: Apparently texture transforms do NOT need reapplying
3915 glMatrixMode(GL_MODELVIEW);
3916 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3917 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3918 checkGLcall("glLoadMatrixf(...)");
3920 /* Reset lights. TODO: Call light apply func */
3921 for (k = 0; k < gl_info->limits.lights; ++k)
3923 if (!(light = state->lights[k]))
3924 continue;
3925 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3926 checkGLcall("glLightfv posn");
3927 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3928 checkGLcall("glLightfv dirn");
3931 /* Reset Clipping Planes */
3932 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3934 if (!isStateDirty(context, STATE_CLIPPLANE(k)))
3935 clipplane(context, state, STATE_CLIPPLANE(k));
3938 if(context->last_was_rhw) {
3939 glLoadIdentity();
3940 checkGLcall("glLoadIdentity()");
3941 /* No need to update the world matrix, the identity is fine */
3942 return;
3945 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3946 * No need to do it here if the state is scheduled for update. */
3947 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
3948 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
3950 /* Avoid looping over a number of matrices if the app never used the functionality */
3951 if (context->swapchain->device->vertexBlendUsed)
3953 for (k = 1; k < gl_info->limits.blends; ++k)
3955 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
3956 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
3961 static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3963 glMatrixMode(GL_PROJECTION);
3964 checkGLcall("glMatrixMode(GL_PROJECTION)");
3966 /* There are a couple of additional things we have to take into account
3967 * here besides the projection transformation itself:
3968 * - We need to flip along the y-axis in case of offscreen rendering.
3969 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
3970 * - D3D coordinates refer to pixel centers while GL coordinates refer
3971 * to pixel corners.
3972 * - D3D has a top-left filling convention. We need to maintain this
3973 * even after the y-flip mentioned above.
3974 * In order to handle the last two points, we translate by
3975 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
3976 * translating slightly less than half a pixel. We want the difference to
3977 * be large enough that it doesn't get lost due to rounding inside the
3978 * driver, but small enough to prevent it from interfering with any
3979 * anti-aliasing. */
3981 if (context->last_was_rhw)
3983 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
3984 double x = state->viewport.x;
3985 double y = state->viewport.y;
3986 double w = state->viewport.width;
3987 double h = state->viewport.height;
3988 double x_scale = 2.0 / w;
3989 double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
3990 double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
3991 double y_offset = context->render_offscreen
3992 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
3993 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
3994 const GLdouble projection[] =
3996 x_scale, 0.0, 0.0, 0.0,
3997 0.0, y_scale, 0.0, 0.0,
3998 0.0, 0.0, 2.0, 0.0,
3999 x_offset, y_offset, -1.0, 1.0,
4002 glLoadMatrixd(projection);
4003 checkGLcall("glLoadMatrixd");
4005 else
4007 double y_scale = context->render_offscreen ? -1.0 : 1.0;
4008 double x_offset = (63.0 / 64.0) / state->viewport.width;
4009 double y_offset = context->render_offscreen
4010 ? (63.0 / 64.0) / state->viewport.height
4011 : -(63.0 / 64.0) / state->viewport.height;
4012 const GLdouble projection[] =
4014 1.0, 0.0, 0.0, 0.0,
4015 0.0, y_scale, 0.0, 0.0,
4016 0.0, 0.0, 2.0, 0.0,
4017 x_offset, y_offset, -1.0, 1.0,
4020 glLoadMatrixd(projection);
4021 checkGLcall("glLoadMatrixd");
4023 glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4024 checkGLcall("glLoadMatrixf");
4028 /* This should match any arrays loaded in load_vertex_data.
4029 * TODO: Only load / unload arrays if we have to. */
4030 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4032 glDisableClientState(GL_VERTEX_ARRAY);
4033 glDisableClientState(GL_NORMAL_ARRAY);
4034 glDisableClientState(GL_COLOR_ARRAY);
4035 if (gl_info->supported[EXT_SECONDARY_COLOR])
4037 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4039 if (gl_info->supported[ARB_VERTEX_BLEND])
4041 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4043 unload_tex_coords(gl_info);
4046 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4048 const struct wined3d_gl_info *gl_info = context->gl_info;
4050 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4051 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4053 context->numbered_array_mask &= ~(1 << i);
4056 /* This should match any arrays loaded in loadNumberedArrays
4057 * TODO: Only load / unload arrays if we have to. */
4058 static void unload_numbered_arrays(struct wined3d_context *context)
4060 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4061 int i;
4063 for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4064 unload_numbered_array(context, i);
4068 static void load_numbered_arrays(struct wined3d_context *context,
4069 const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4071 struct wined3d_device *device = context->swapchain->device;
4072 const struct wined3d_gl_info *gl_info = context->gl_info;
4073 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4074 int i;
4076 /* Default to no instancing */
4077 device->instancedDraw = FALSE;
4079 for (i = 0; i < MAX_ATTRIBS; i++)
4081 const struct wined3d_stream_state *stream;
4083 if (!(stream_info->use_map & (1 << i)))
4085 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4086 continue;
4089 stream = &state->streams[stream_info->elements[i].stream_idx];
4091 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4092 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4094 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4095 device->instancedDraw = TRUE;
4096 continue;
4099 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4101 if (stream_info->elements[i].stride)
4103 if (curVBO != stream_info->elements[i].data.buffer_object)
4105 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4106 checkGLcall("glBindBufferARB");
4107 curVBO = stream_info->elements[i].data.buffer_object;
4109 /* Use the VBO to find out if a vertex buffer exists, not the vb
4110 * pointer. vb can point to a user pointer data blob. In that case
4111 * curVBO will be 0. If there is a vertex buffer but no vbo we
4112 * won't be load converted attributes anyway. */
4113 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4114 stream_info->elements[i].format->gl_vtx_type,
4115 stream_info->elements[i].format->gl_normalized,
4116 stream_info->elements[i].stride, stream_info->elements[i].data.addr
4117 + state->load_base_vertex_index * stream_info->elements[i].stride));
4119 if (!(context->numbered_array_mask & (1 << i)))
4121 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4122 context->numbered_array_mask |= (1 << i);
4125 else
4127 /* Stride = 0 means always the same values.
4128 * glVertexAttribPointerARB doesn't do that. Instead disable the
4129 * pointer and set up the attribute statically. But we have to
4130 * figure out the system memory address. */
4131 const BYTE *ptr = stream_info->elements[i].data.addr;
4132 if (stream_info->elements[i].data.buffer_object)
4134 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4137 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4139 switch (stream_info->elements[i].format->id)
4141 case WINED3DFMT_R32_FLOAT:
4142 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4143 break;
4144 case WINED3DFMT_R32G32_FLOAT:
4145 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4146 break;
4147 case WINED3DFMT_R32G32B32_FLOAT:
4148 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4149 break;
4150 case WINED3DFMT_R32G32B32A32_FLOAT:
4151 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4152 break;
4154 case WINED3DFMT_R8G8B8A8_UINT:
4155 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4156 break;
4157 case WINED3DFMT_B8G8R8A8_UNORM:
4158 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4160 const DWORD *src = (const DWORD *)ptr;
4161 DWORD c = *src & 0xff00ff00;
4162 c |= (*src & 0xff0000) >> 16;
4163 c |= (*src & 0xff) << 16;
4164 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4165 break;
4167 /* else fallthrough */
4168 case WINED3DFMT_R8G8B8A8_UNORM:
4169 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4170 break;
4172 case WINED3DFMT_R16G16_SINT:
4173 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4174 break;
4175 case WINED3DFMT_R16G16B16A16_SINT:
4176 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4177 break;
4179 case WINED3DFMT_R16G16_SNORM:
4181 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4182 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4183 break;
4185 case WINED3DFMT_R16G16_UNORM:
4187 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4188 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4189 break;
4191 case WINED3DFMT_R16G16B16A16_SNORM:
4192 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4193 break;
4194 case WINED3DFMT_R16G16B16A16_UNORM:
4195 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4196 break;
4198 case WINED3DFMT_R10G10B10A2_UINT:
4199 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4200 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4201 break;
4202 case WINED3DFMT_R10G10B10A2_SNORM:
4203 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4204 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4205 break;
4207 case WINED3DFMT_R16G16_FLOAT:
4208 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4209 * byte float according to the IEEE standard
4211 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4212 break;
4213 case WINED3DFMT_R16G16B16A16_FLOAT:
4214 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4215 break;
4217 default:
4218 ERR("Unexpected declaration in stride 0 attributes\n");
4219 break;
4224 checkGLcall("Loading numbered arrays");
4227 static void load_vertex_data(const struct wined3d_context *context,
4228 const struct wined3d_stream_info *si, const struct wined3d_state *state)
4230 struct wined3d_device *device = context->swapchain->device;
4231 const struct wined3d_gl_info *gl_info = context->gl_info;
4232 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4233 const struct wined3d_stream_info_element *e;
4235 TRACE("Using fast vertex array code\n");
4237 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4238 device->instancedDraw = FALSE;
4240 /* Blend Data ---------------------------------------------- */
4241 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4242 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4244 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4246 if (gl_info->supported[ARB_VERTEX_BLEND])
4248 TRACE("Blend %u %p %u\n", e->format->component_count,
4249 e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4251 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4252 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4254 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4256 if (curVBO != e->data.buffer_object)
4258 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4259 checkGLcall("glBindBufferARB");
4260 curVBO = e->data.buffer_object;
4263 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4264 e->format->gl_vtx_format,
4265 e->format->gl_vtx_type,
4266 e->stride,
4267 e->data.addr + state->load_base_vertex_index * e->stride);
4268 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4269 e->data.addr + state->load_base_vertex_index * e->stride));
4271 checkGLcall("glWeightPointerARB");
4273 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4275 static BOOL warned;
4276 if (!warned)
4278 FIXME("blendMatrixIndices support\n");
4279 warned = TRUE;
4282 } else {
4283 /* TODO: support blends in drawStridedSlow
4284 * No need to write a FIXME here, this is done after the general vertex decl decoding
4286 WARN("unsupported blending in openGl\n");
4289 else
4291 if (gl_info->supported[ARB_VERTEX_BLEND])
4293 static const GLbyte one = 1;
4294 GL_EXTCALL(glWeightbvARB(1, &one));
4295 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4299 /* Point Size ----------------------------------------------*/
4300 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4302 /* no such functionality in the fixed function GL pipeline */
4303 TRACE("Cannot change ptSize here in openGl\n");
4304 /* TODO: Implement this function in using shaders if they are available */
4307 /* Vertex Pointers -----------------------------------------*/
4308 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4310 e = &si->elements[WINED3D_FFP_POSITION];
4312 if (curVBO != e->data.buffer_object)
4314 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4315 checkGLcall("glBindBufferARB");
4316 curVBO = e->data.buffer_object;
4319 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4320 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4321 e->data.addr + state->load_base_vertex_index * e->stride);
4322 glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4323 e->data.addr + state->load_base_vertex_index * e->stride);
4324 checkGLcall("glVertexPointer(...)");
4325 glEnableClientState(GL_VERTEX_ARRAY);
4326 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4329 /* Normals -------------------------------------------------*/
4330 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4332 e = &si->elements[WINED3D_FFP_NORMAL];
4334 if (curVBO != e->data.buffer_object)
4336 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4337 checkGLcall("glBindBufferARB");
4338 curVBO = e->data.buffer_object;
4341 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4342 e->data.addr + state->load_base_vertex_index * e->stride);
4343 glNormalPointer(e->format->gl_vtx_type, e->stride,
4344 e->data.addr + state->load_base_vertex_index * e->stride);
4345 checkGLcall("glNormalPointer(...)");
4346 glEnableClientState(GL_NORMAL_ARRAY);
4347 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4349 } else {
4350 glNormal3f(0, 0, 0);
4351 checkGLcall("glNormal3f(0, 0, 0)");
4354 /* Diffuse Colour --------------------------------------------*/
4355 /* WARNING: Data here MUST be in RGBA format, so cannot */
4356 /* go directly into fast mode from app pgm, because */
4357 /* directx requires data in BGRA format. */
4358 /* currently fixupVertices swizzles the format, but this isn't*/
4359 /* very practical when using VBOs */
4360 /* NOTE: Unless we write a vertex shader to swizzle the colour*/
4361 /* , or the user doesn't care and wants the speed advantage */
4363 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4365 e = &si->elements[WINED3D_FFP_DIFFUSE];
4367 if (curVBO != e->data.buffer_object)
4369 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4370 checkGLcall("glBindBufferARB");
4371 curVBO = e->data.buffer_object;
4374 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4375 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4376 e->data.addr + state->load_base_vertex_index * e->stride);
4377 glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4378 e->data.addr + state->load_base_vertex_index * e->stride);
4379 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4380 glEnableClientState(GL_COLOR_ARRAY);
4381 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4383 } else {
4384 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4385 checkGLcall("glColor4f(1, 1, 1, 1)");
4388 /* Specular Colour ------------------------------------------*/
4389 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4391 TRACE("setting specular colour\n");
4393 e = &si->elements[WINED3D_FFP_SPECULAR];
4395 if (gl_info->supported[EXT_SECONDARY_COLOR])
4397 GLenum type = e->format->gl_vtx_type;
4398 GLint format = e->format->gl_vtx_format;
4400 if (curVBO != e->data.buffer_object)
4402 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4403 checkGLcall("glBindBufferARB");
4404 curVBO = e->data.buffer_object;
4407 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4409 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4410 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4411 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4412 * 4 component secondary colors use it
4414 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4415 e->data.addr + state->load_base_vertex_index * e->stride);
4416 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4417 e->data.addr + state->load_base_vertex_index * e->stride));
4418 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4420 else
4422 switch(type)
4424 case GL_UNSIGNED_BYTE:
4425 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4426 e->data.addr + state->load_base_vertex_index * e->stride);
4427 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4428 e->data.addr + state->load_base_vertex_index * e->stride));
4429 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4430 break;
4432 default:
4433 FIXME("Add 4 component specular color pointers for type %x\n", type);
4434 /* Make sure that the right color component is dropped */
4435 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4436 e->data.addr + state->load_base_vertex_index * e->stride);
4437 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4438 e->data.addr + state->load_base_vertex_index * e->stride));
4439 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4442 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4443 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4445 else
4447 WARN("Specular colour is not supported in this GL implementation.\n");
4450 else
4452 if (gl_info->supported[EXT_SECONDARY_COLOR])
4454 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4455 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4457 else
4459 WARN("Specular colour is not supported in this GL implementation.\n");
4463 /* Texture coords -------------------------------------------*/
4464 load_tex_coords(context, si, &curVBO, state);
4467 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4469 const struct wined3d_device *device = context->swapchain->device;
4470 BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4471 BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4473 if (isStateDirty(context, STATE_VDECL)) return;
4474 if (context->numberedArraysLoaded && !load_numbered)
4476 unload_numbered_arrays(context);
4477 context->numberedArraysLoaded = FALSE;
4478 context->numbered_array_mask = 0;
4480 else if (context->namedArraysLoaded)
4482 unload_vertex_data(context->gl_info);
4483 context->namedArraysLoaded = FALSE;
4486 if (load_numbered)
4488 TRACE("Loading numbered arrays\n");
4489 load_numbered_arrays(context, &device->strided_streams, state);
4490 context->numberedArraysLoaded = TRUE;
4492 else if (load_named)
4494 TRACE("Loading vertex data\n");
4495 load_vertex_data(context, &device->strided_streams, state);
4496 context->namedArraysLoaded = TRUE;
4500 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4502 if (isStateDirty(context, STATE_STREAMSRC))
4503 return;
4504 streamsrc(context, state, STATE_STREAMSRC);
4507 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4509 const struct wined3d_device *device = context->swapchain->device;
4510 const struct wined3d_gl_info *gl_info = context->gl_info;
4511 BOOL useVertexShaderFunction = use_vs(state);
4512 BOOL usePixelShaderFunction = use_ps(state);
4513 BOOL updateFog = FALSE;
4514 BOOL transformed;
4515 BOOL wasrhw = context->last_was_rhw;
4516 unsigned int i;
4518 transformed = device->strided_streams.position_transformed;
4519 if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4520 updateFog = TRUE;
4522 context->last_was_rhw = transformed;
4524 /* Don't have to apply the matrices when vertex shaders are used. When
4525 * vshaders are turned off this function will be called again anyway to
4526 * make sure they're properly set. */
4527 if (!useVertexShaderFunction)
4529 /* TODO: Move this mainly to the viewport state and only apply when
4530 * the vp has changed or transformed / untransformed was switched. */
4531 if (wasrhw != context->last_was_rhw
4532 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4533 && !isStateDirty(context, STATE_VIEWPORT))
4534 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4535 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4536 * mode.
4538 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4539 * this check will fail and the matrix not applied again. This is OK because a simple
4540 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4541 * needs of the vertex declaration.
4543 * World and view matrix go into the same gl matrix, so only apply them when neither is
4544 * dirty
4546 if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4547 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4548 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4549 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4550 state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4551 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4552 state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4554 if (context->last_was_vshader)
4556 updateFog = TRUE;
4558 if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4559 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4561 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4563 clipplane(context, state, STATE_CLIPPLANE(i));
4566 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4567 state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4569 else
4571 if(!context->last_was_vshader) {
4572 static BOOL warned = FALSE;
4573 if(!device->vs_clipping) {
4574 /* Disable all clip planes to get defined results on all drivers. See comment in the
4575 * state_clipping state handler
4577 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4579 glDisable(GL_CLIP_PLANE0 + i);
4580 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4583 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4585 FIXME("Clipping not supported with vertex shaders\n");
4586 warned = TRUE;
4589 if (wasrhw)
4591 /* Apply the transform matrices when switching from rhw
4592 * drawing to vertex shaders. Vertex shaders themselves do
4593 * not need it, but the matrices are not reapplied
4594 * automatically when switching back from vertex shaders to
4595 * fixed function processing. So make sure we leave the fixed
4596 * function vertex processing states back in a sane state
4597 * before switching to shaders. */
4598 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4599 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4600 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4601 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4603 updateFog = TRUE;
4605 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4606 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4607 * device->vs_clipping is false.
4609 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4611 clipplane(context, state, STATE_CLIPPLANE(i));
4616 /* Vertex and pixel shaders are applied together, so let the last dirty
4617 * state do the application. */
4618 if (!isStateDirty(context, STATE_PIXELSHADER))
4620 device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4622 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)
4623 && (useVertexShaderFunction || usePixelShaderFunction))
4624 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4627 context->last_was_vshader = useVertexShaderFunction;
4629 if (updateFog)
4630 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4632 if (!useVertexShaderFunction)
4634 unsigned int i;
4636 for (i = 0; i < MAX_TEXTURES; ++i)
4638 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4639 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4643 if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4644 state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4647 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4649 const struct wined3d_surface *target = state->fb->render_targets[0];
4650 struct wined3d_viewport vp = state->viewport;
4652 if (vp.width > target->resource.width)
4653 vp.width = target->resource.width;
4654 if (vp.height > target->resource.height)
4655 vp.height = target->resource.height;
4657 glDepthRange(vp.min_z, vp.max_z);
4658 checkGLcall("glDepthRange");
4659 /* Note: GL requires lower left, DirectX supplies upper left. This is
4660 * reversed when using offscreen rendering. */
4661 if (context->render_offscreen)
4663 glViewport(vp.x, vp.y, vp.width, vp.height);
4665 else
4667 UINT width, height;
4669 target->get_drawable_size(context, &width, &height);
4670 glViewport(vp.x, (height - (vp.y + vp.height)),
4671 vp.width, vp.height);
4674 checkGLcall("glViewport");
4677 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4679 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4680 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4681 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4682 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4683 /* Update the position fixup. */
4684 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
4685 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4688 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4690 UINT Index = state_id - STATE_ACTIVELIGHT(0);
4691 const struct wined3d_light_info *lightInfo = state->lights[Index];
4693 if (!lightInfo)
4695 glDisable(GL_LIGHT0 + Index);
4696 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4698 else
4700 float quad_att;
4701 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4703 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4704 glMatrixMode(GL_MODELVIEW);
4705 glPushMatrix();
4706 glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4708 /* Diffuse: */
4709 colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4710 colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4711 colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4712 colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4713 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4714 checkGLcall("glLightfv");
4716 /* Specular */
4717 colRGBA[0] = lightInfo->OriginalParms.specular.r;
4718 colRGBA[1] = lightInfo->OriginalParms.specular.g;
4719 colRGBA[2] = lightInfo->OriginalParms.specular.b;
4720 colRGBA[3] = lightInfo->OriginalParms.specular.a;
4721 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4722 checkGLcall("glLightfv");
4724 /* Ambient */
4725 colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4726 colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4727 colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4728 colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4729 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4730 checkGLcall("glLightfv");
4732 if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4733 quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4734 else
4735 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4737 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4738 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4739 * Attenuation0 to NaN and crashes in the gl lib
4742 switch (lightInfo->OriginalParms.type)
4744 case WINED3D_LIGHT_POINT:
4745 /* Position */
4746 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4747 checkGLcall("glLightfv");
4748 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4749 checkGLcall("glLightf");
4750 /* Attenuation - Are these right? guessing... */
4751 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4752 checkGLcall("glLightf");
4753 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4754 checkGLcall("glLightf");
4755 if (quad_att < lightInfo->OriginalParms.attenuation2)
4756 quad_att = lightInfo->OriginalParms.attenuation2;
4757 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4758 checkGLcall("glLightf");
4759 /* FIXME: Range */
4760 break;
4762 case WINED3D_LIGHT_SPOT:
4763 /* Position */
4764 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4765 checkGLcall("glLightfv");
4766 /* Direction */
4767 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4768 checkGLcall("glLightfv");
4769 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4770 checkGLcall("glLightf");
4771 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4772 checkGLcall("glLightf");
4773 /* Attenuation - Are these right? guessing... */
4774 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
4775 checkGLcall("glLightf");
4776 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
4777 checkGLcall("glLightf");
4778 if (quad_att < lightInfo->OriginalParms.attenuation2)
4779 quad_att = lightInfo->OriginalParms.attenuation2;
4780 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4781 checkGLcall("glLightf");
4782 /* FIXME: Range */
4783 break;
4785 case WINED3D_LIGHT_DIRECTIONAL:
4786 /* Direction */
4787 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4788 checkGLcall("glLightfv");
4789 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4790 checkGLcall("glLightf");
4791 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4792 checkGLcall("glLightf");
4793 break;
4795 default:
4796 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4799 /* Restore the modelview matrix */
4800 glPopMatrix();
4802 glEnable(GL_LIGHT0 + Index);
4803 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4807 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4809 const RECT *r = &state->scissor_rect;
4811 /* Warning: glScissor uses window coordinates, not viewport coordinates,
4812 * so our viewport correction does not apply. Warning2: Even in windowed
4813 * mode the coords are relative to the window, not the screen. */
4814 TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4816 if (context->render_offscreen)
4818 glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4820 else
4822 const struct wined3d_surface *target = state->fb->render_targets[0];
4823 UINT height;
4824 UINT width;
4826 target->get_drawable_size(context, &width, &height);
4827 glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4829 checkGLcall("glScissor");
4832 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4834 const struct wined3d_gl_info *gl_info = context->gl_info;
4836 if (state->user_stream || !state->index_buffer)
4838 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4840 else
4842 struct wined3d_buffer *ib = state->index_buffer;
4843 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4847 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4849 if (context->render_offscreen)
4851 glFrontFace(GL_CCW);
4852 checkGLcall("glFrontFace(GL_CCW)");
4853 } else {
4854 glFrontFace(GL_CW);
4855 checkGLcall("glFrontFace(GL_CW)");
4859 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4861 static BOOL warned;
4863 if (!warned)
4865 WARN("Point sprite coordinate origin switching not supported.\n");
4866 warned = TRUE;
4870 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4872 const struct wined3d_gl_info *gl_info = context->gl_info;
4873 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4875 if (glPointParameteri)
4877 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin);
4878 checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4880 else if (gl_info->supported[NV_POINT_SPRITE])
4882 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4883 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4887 const struct StateEntryTemplate misc_state_template[] = {
4888 { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4889 { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4890 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4891 { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4892 { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4893 { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4894 { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4895 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4896 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4897 { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4898 { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
4899 { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
4900 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4901 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4902 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4903 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4905 /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4906 * vshader loadings are untied from each other
4908 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4909 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4910 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4911 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4912 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4913 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4914 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4915 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4916 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4917 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4918 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4919 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4920 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4921 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4922 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4923 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4924 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4925 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4926 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4927 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4928 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4929 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4930 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4931 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4932 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4933 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4934 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4935 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4936 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4937 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4938 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4939 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4940 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4941 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4942 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4943 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4944 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4945 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4946 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4947 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4948 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4949 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4950 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4951 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4952 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4953 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4954 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4955 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4956 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4957 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
4959 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
4960 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
4961 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
4962 { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
4963 { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
4964 { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
4965 { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
4966 { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
4967 { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
4968 { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
4969 { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
4970 { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
4971 { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
4972 { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
4973 { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
4974 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
4975 { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4976 { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4977 { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
4978 { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
4979 { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
4980 { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
4981 { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
4982 { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
4983 { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
4984 { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
4985 { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
4986 { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
4987 { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
4988 { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
4989 { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
4990 { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4991 { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4992 { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4993 { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4994 { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4995 { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4996 { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
4997 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
4998 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
4999 { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5000 { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5001 { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5003 { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5004 { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5005 { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5006 { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5007 { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5008 { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5009 { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5010 { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5011 { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5012 { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5013 { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5014 { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5015 { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5016 { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5017 { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5018 { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5019 { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5020 { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5021 { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5022 { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5023 { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5024 { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5025 { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5026 { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5027 { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5028 { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5029 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5030 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5031 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5032 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5033 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5034 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
5035 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5036 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5037 { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5038 { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5039 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5040 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5042 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5044 { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5045 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5046 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5047 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5048 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5050 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5051 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5052 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5053 { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5054 { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5055 /* Samplers */
5056 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5057 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5058 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5059 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5060 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5061 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5062 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5063 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5064 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5065 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5066 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5067 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5068 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5069 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5070 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5071 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5072 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5073 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5074 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5075 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5076 { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
5077 { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
5078 { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
5079 { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
5080 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5083 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5084 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5085 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5086 { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5087 { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5088 /* Clip planes */
5089 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5090 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5091 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5092 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5093 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5094 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5095 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5096 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5097 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5098 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5099 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5100 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5101 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5102 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5103 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5104 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5105 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5106 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5107 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5108 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5109 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5110 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5111 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5112 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5113 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5114 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5115 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5116 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5117 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5118 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5119 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5120 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5121 /* Lights */
5122 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5123 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5124 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5125 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5126 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5127 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5128 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5129 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5130 /* Viewport */
5131 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5132 /* Transform states follow */
5133 { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5134 { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5135 { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5136 { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5137 { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5138 { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5139 { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5140 { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5141 { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5142 { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5143 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5144 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5145 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5146 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5147 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5148 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5149 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5150 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5151 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5152 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5153 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5154 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5155 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5156 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5157 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5158 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5159 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5160 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5161 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5162 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5163 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5164 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5165 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5166 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5167 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5168 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5169 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5170 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5171 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5172 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5173 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5174 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5175 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5176 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5177 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5178 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5179 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5180 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5181 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5182 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5183 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5184 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5185 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5186 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5187 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5188 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5189 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5190 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5191 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5192 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5193 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5194 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5195 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5396 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5397 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5400 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5401 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5402 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5403 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5404 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5405 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5406 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5407 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5411 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5412 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5413 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5414 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5415 /* Fog */
5416 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5417 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5418 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5419 { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5420 { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5421 { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5422 { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5423 { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5424 { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5425 { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5426 { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5427 { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5428 { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5429 { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5430 { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5431 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5432 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5433 { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5434 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5435 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5436 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5437 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5438 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5439 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5440 { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5441 { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5442 { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5443 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5444 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5445 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5446 { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5447 { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5449 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5450 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5451 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5453 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5454 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5455 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5456 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5457 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5458 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5459 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5460 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5461 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5462 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5463 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5464 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5465 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5466 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5467 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5468 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5469 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5470 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5471 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5472 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5473 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5474 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5475 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5476 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5477 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5480 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5481 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5482 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5483 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5484 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5485 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5486 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5487 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5488 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5489 { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5490 { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5491 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5492 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5493 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5494 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5495 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5496 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5497 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5498 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5499 { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5500 { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5501 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5502 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5503 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5504 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5505 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5506 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5507 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5508 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5509 { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5510 { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5511 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5512 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5513 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5514 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5515 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5516 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5517 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5518 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5519 { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5520 { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5521 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5522 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5523 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5524 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5525 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5526 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5527 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5528 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5529 { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5530 { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5531 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5532 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5533 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5534 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5535 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5536 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5537 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5538 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5539 { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5540 { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5541 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5542 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5543 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5544 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5545 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5546 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5547 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5548 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5549 { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5550 { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5551 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5552 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5553 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5554 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5555 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5556 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5557 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5558 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5559 { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5560 { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5561 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5562 { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5563 { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5564 { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5565 { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5566 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5567 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5568 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5569 { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5570 { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5571 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5572 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5573 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5574 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5575 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5576 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5577 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5578 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5579 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5582 /* Context activation and GL locking are done by the caller. */
5583 static void ffp_enable(BOOL enable) {}
5585 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5587 caps->PrimitiveMiscCaps = 0;
5588 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5589 | WINED3DTEXOPCAPS_ADDSIGNED
5590 | WINED3DTEXOPCAPS_ADDSIGNED2X
5591 | WINED3DTEXOPCAPS_MODULATE
5592 | WINED3DTEXOPCAPS_MODULATE2X
5593 | WINED3DTEXOPCAPS_MODULATE4X
5594 | WINED3DTEXOPCAPS_SELECTARG1
5595 | WINED3DTEXOPCAPS_SELECTARG2
5596 | WINED3DTEXOPCAPS_DISABLE;
5598 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5599 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5600 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5602 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5603 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5604 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5605 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5606 | WINED3DTEXOPCAPS_LERP
5607 | WINED3DTEXOPCAPS_SUBTRACT;
5609 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5610 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5612 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5613 | WINED3DTEXOPCAPS_MULTIPLYADD
5614 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5615 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5616 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5618 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5619 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5621 caps->MaxTextureBlendStages = gl_info->limits.textures;
5622 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5625 static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; }
5626 static void ffp_fragment_free(struct wined3d_device *device) {}
5627 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5629 if (TRACE_ON(d3d))
5631 TRACE("Checking support for fixup:\n");
5632 dump_color_fixup_desc(fixup);
5635 /* We only support identity conversions. */
5636 if (is_identity_fixup(fixup))
5638 TRACE("[OK]\n");
5639 return TRUE;
5642 TRACE("[FAILED]\n");
5643 return FALSE;
5646 const struct fragment_pipeline ffp_fragment_pipeline = {
5647 ffp_enable,
5648 ffp_fragment_get_caps,
5649 ffp_fragment_alloc,
5650 ffp_fragment_free,
5651 ffp_color_fixup_supported,
5652 ffp_fragmentstate_template,
5653 FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5656 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5658 unsigned int i;
5659 for(i = 0; funcs[i]; i++);
5660 return i;
5663 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5665 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5666 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5669 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5671 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5672 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5673 context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5676 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5678 unsigned int start, last, i;
5680 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5681 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5682 for (i = start; i <= last; ++i)
5684 state_table[i].representative = 0;
5685 state_table[i].apply = state_undefined;
5688 start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
5689 last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5690 for (i = start; i <= last; ++i)
5692 state_table[i].representative = 0;
5693 state_table[i].apply = state_undefined;
5696 start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5697 last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5698 for (i = start; i <= last; ++i)
5700 state_table[i].representative = 0;
5701 state_table[i].apply = state_undefined;
5705 static void validate_state_table(struct StateEntry *state_table)
5707 static const struct
5709 DWORD first;
5710 DWORD last;
5712 rs_holes[] =
5714 { 1, 1},
5715 { 3, 3},
5716 { 17, 18},
5717 { 21, 21},
5718 { 42, 45},
5719 { 47, 47},
5720 { 61, 127},
5721 {149, 150},
5722 {169, 169},
5723 {177, 177},
5724 {196, 197},
5725 { 0, 0},
5727 static const DWORD simple_states[] =
5729 STATE_MATERIAL,
5730 STATE_VDECL,
5731 STATE_STREAMSRC,
5732 STATE_INDEXBUFFER,
5733 STATE_VERTEXSHADERCONSTANT,
5734 STATE_PIXELSHADERCONSTANT,
5735 STATE_VSHADER,
5736 STATE_PIXELSHADER,
5737 STATE_VIEWPORT,
5738 STATE_SCISSORRECT,
5739 STATE_FRONTFACE,
5740 STATE_POINTSPRITECOORDORIGIN,
5741 STATE_BASEVERTEXINDEX,
5742 STATE_FRAMEBUFFER
5744 unsigned int i, current;
5746 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5748 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5750 if (!state_table[i].representative)
5751 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5753 else if (state_table[i].representative)
5754 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5756 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5759 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5761 if (!state_table[simple_states[i]].representative)
5762 ERR("State %s (%#x) should have a representative.\n",
5763 debug_d3dstate(simple_states[i]), simple_states[i]);
5766 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5768 DWORD rep = state_table[i].representative;
5769 if (rep)
5771 if (state_table[rep].representative != rep)
5773 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5774 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5775 state_table[i].representative = 0;
5778 if (rep != i)
5780 if (state_table[i].apply)
5781 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5783 else if (!state_table[i].apply)
5785 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5791 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5792 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5793 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5795 unsigned int i, type, handlers;
5796 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5797 const struct StateEntryTemplate *cur;
5798 BOOL set[STATE_HIGHEST + 1];
5800 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5802 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5803 StateTable[i].representative = 0;
5804 StateTable[i].apply = state_undefined;
5807 for(type = 0; type < 3; type++) {
5808 /* This switch decides the order in which the states are applied */
5809 switch(type) {
5810 case 0: cur = misc; break;
5811 case 1: cur = fragment->states; break;
5812 case 2: cur = vertex; break;
5813 default: cur = NULL; /* Stupid compiler */
5815 if(!cur) continue;
5817 /* GL extension filtering should not prevent multiple handlers being applied from different
5818 * pipeline parts
5820 memset(set, 0, sizeof(set));
5822 for(i = 0; cur[i].state; i++) {
5823 APPLYSTATEFUNC *funcs_array;
5825 /* Only use the first matching state with the available extension from one template.
5826 * e.g.
5827 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5828 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5830 * if GL_XYZ_fancy is supported, ignore the 2nd line
5832 if(set[cur[i].state]) continue;
5833 /* Skip state lines depending on unsupported extensions */
5834 if (!gl_info->supported[cur[i].extension]) continue;
5835 set[cur[i].state] = TRUE;
5836 /* In some cases having an extension means that nothing has to be
5837 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5838 * supported, the texture coordinate fixup can be ignored. If the
5839 * apply function is used, mark the state set(done above) to prevent
5840 * applying later lines, but do not record anything in the state
5841 * table
5843 if (!cur[i].content.representative) continue;
5845 handlers = num_handlers(multistate_funcs[cur[i].state]);
5846 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5847 switch(handlers) {
5848 case 0:
5849 StateTable[cur[i].state].apply = cur[i].content.apply;
5850 break;
5851 case 1:
5852 StateTable[cur[i].state].apply = multistate_apply_2;
5853 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5855 sizeof(**dev_multistate_funcs) * 2);
5856 if (!dev_multistate_funcs[cur[i].state]) {
5857 goto out_of_mem;
5860 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5861 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5862 break;
5863 case 2:
5864 StateTable[cur[i].state].apply = multistate_apply_3;
5865 funcs_array = HeapReAlloc(GetProcessHeap(),
5867 dev_multistate_funcs[cur[i].state],
5868 sizeof(**dev_multistate_funcs) * 3);
5869 if (!funcs_array) {
5870 goto out_of_mem;
5873 dev_multistate_funcs[cur[i].state] = funcs_array;
5874 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5875 break;
5876 default:
5877 ERR("Unexpected amount of state handlers for state %u: %u\n",
5878 cur[i].state, handlers + 1);
5881 if(StateTable[cur[i].state].representative &&
5882 StateTable[cur[i].state].representative != cur[i].content.representative) {
5883 FIXME("State %u has different representatives in different pipeline parts\n",
5884 cur[i].state);
5886 StateTable[cur[i].state].representative = cur[i].content.representative;
5890 prune_invalid_states(StateTable, gl_info);
5891 validate_state_table(StateTable);
5893 return WINED3D_OK;
5895 out_of_mem:
5896 for (i = 0; i <= STATE_HIGHEST; ++i) {
5897 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5900 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5902 return E_OUTOFMEMORY;