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
29 #include "wine/port.h"
36 #include "wined3d_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
39 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
41 /* Context activation for state handler is done by the caller. */
43 static void state_undefined(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
45 ERR("Undefined state.\n");
48 static void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
50 TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state_id));
53 static void state_fillmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
55 enum wined3d_fill_mode mode = state->render_states[WINED3D_RS_FILLMODE];
56 const struct wined3d_gl_info *gl_info = context->gl_info;
60 case WINED3D_FILL_POINT:
61 gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
62 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
64 case WINED3D_FILL_WIREFRAME:
65 gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
66 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
68 case WINED3D_FILL_SOLID:
69 gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
70 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
73 FIXME("Unrecognized fill mode %#x.\n", mode);
77 static void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
79 const struct wined3d_gl_info *gl_info = context->gl_info;
81 /* Lighting is not enabled if transformed vertices are drawn, but lighting
82 * does not affect the stream sources, so it is not grouped for
83 * performance reasons. This state reads the decoded vertex declaration,
84 * so if it is dirty don't do anything. The vertex declaration applying
85 * function calls this function for updating. */
86 if (isStateDirty(context, STATE_VDECL))
89 if (state->render_states[WINED3D_RS_LIGHTING]
90 && !context->swapchain->device->strided_streams.position_transformed)
92 gl_info->gl_ops.gl.p_glEnable(GL_LIGHTING);
93 checkGLcall("glEnable GL_LIGHTING");
97 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
98 checkGLcall("glDisable GL_LIGHTING");
102 static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
104 enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE];
105 const struct wined3d_gl_info *gl_info = context->gl_info;
108 /* No z test without depth stencil buffers */
109 if (!state->fb->depth_stencil)
111 TRACE("No Z buffer - disabling depth test\n");
112 zenable = WINED3D_ZB_FALSE;
117 case WINED3D_ZB_FALSE:
118 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
119 checkGLcall("glDisable GL_DEPTH_TEST");
121 case WINED3D_ZB_TRUE:
122 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
123 checkGLcall("glEnable GL_DEPTH_TEST");
125 case WINED3D_ZB_USEW:
126 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
127 checkGLcall("glEnable GL_DEPTH_TEST");
128 FIXME("W buffer is not well handled\n");
131 FIXME("Unrecognized depth buffer type %#x.\n", zenable);
135 if (context->gl_info->supported[ARB_DEPTH_CLAMP])
137 if (!zenable && context->swapchain->device->strided_streams.position_transformed)
139 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
140 checkGLcall("glEnable(GL_DEPTH_CLAMP)");
144 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
145 checkGLcall("glDisable(GL_DEPTH_CLAMP)");
148 else if (!zenable && !once++)
149 FIXME("Z buffer disabled, but ARB_depth_clamp isn't supported.\n");
152 static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
154 const struct wined3d_gl_info *gl_info = context->gl_info;
156 /* glFrontFace() is set in context.c at context init and on an
157 * offscreen / onscreen rendering switch. */
158 switch (state->render_states[WINED3D_RS_CULLMODE])
160 case WINED3D_CULL_NONE:
161 gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
162 checkGLcall("glDisable GL_CULL_FACE");
164 case WINED3D_CULL_CW:
165 gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE);
166 checkGLcall("glEnable GL_CULL_FACE");
167 gl_info->gl_ops.gl.p_glCullFace(GL_FRONT);
168 checkGLcall("glCullFace(GL_FRONT)");
170 case WINED3D_CULL_CCW:
171 gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE);
172 checkGLcall("glEnable GL_CULL_FACE");
173 gl_info->gl_ops.gl.p_glCullFace(GL_BACK);
174 checkGLcall("glCullFace(GL_BACK)");
177 FIXME("Unrecognized cull mode %#x.\n",
178 state->render_states[WINED3D_RS_CULLMODE]);
182 static void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
184 const struct wined3d_gl_info *gl_info = context->gl_info;
186 switch (state->render_states[WINED3D_RS_SHADEMODE])
188 case WINED3D_SHADE_FLAT:
189 gl_info->gl_ops.gl.p_glShadeModel(GL_FLAT);
190 checkGLcall("glShadeModel(GL_FLAT)");
192 case WINED3D_SHADE_GOURAUD:
193 gl_info->gl_ops.gl.p_glShadeModel(GL_SMOOTH);
194 checkGLcall("glShadeModel(GL_SMOOTH)");
196 case WINED3D_SHADE_PHONG:
197 FIXME("WINED3D_SHADE_PHONG isn't supported.\n");
200 FIXME("Unrecognized shade mode %#x.\n",
201 state->render_states[WINED3D_RS_SHADEMODE]);
205 static void state_ditherenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
207 const struct wined3d_gl_info *gl_info = context->gl_info;
209 if (state->render_states[WINED3D_RS_DITHERENABLE])
211 gl_info->gl_ops.gl.p_glEnable(GL_DITHER);
212 checkGLcall("glEnable GL_DITHER");
216 gl_info->gl_ops.gl.p_glDisable(GL_DITHER);
217 checkGLcall("glDisable GL_DITHER");
221 static void state_zwritenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
223 const struct wined3d_gl_info *gl_info = context->gl_info;
225 if (state->render_states[WINED3D_RS_ZWRITEENABLE])
227 gl_info->gl_ops.gl.p_glDepthMask(1);
228 checkGLcall("glDepthMask(1)");
232 gl_info->gl_ops.gl.p_glDepthMask(0);
233 checkGLcall("glDepthMask(0)");
237 static GLenum gl_compare_func(enum wined3d_cmp_func f)
241 case WINED3D_CMP_NEVER:
243 case WINED3D_CMP_LESS:
245 case WINED3D_CMP_EQUAL:
247 case WINED3D_CMP_LESSEQUAL:
249 case WINED3D_CMP_GREATER:
251 case WINED3D_CMP_NOTEQUAL:
253 case WINED3D_CMP_GREATEREQUAL:
255 case WINED3D_CMP_ALWAYS:
258 FIXME("Unrecognized compare function %#x.\n", f);
263 static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
265 GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
266 const struct wined3d_gl_info *gl_info = context->gl_info;
268 if (!depth_func) return;
270 if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL)
273 /* There are a few issues with this: First, our inability to
274 * select a proper Z depth, most of the time we're stuck with
275 * D24S8, even if the app selects D32 or D16. There seem to be
276 * some other precision problems which have to be debugged to
277 * make NOTEQUAL and EQUAL work properly. */
281 FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet.\n");
285 gl_info->gl_ops.gl.p_glDepthFunc(depth_func);
286 checkGLcall("glDepthFunc");
289 static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
291 const struct wined3d_gl_info *gl_info = context->gl_info;
294 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col);
295 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
296 gl_info->gl_ops.gl.p_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
297 checkGLcall("glLightModel for MODEL_AMBIENT");
300 static void state_blendop_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
302 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
305 static GLenum gl_blend_op(enum wined3d_blend_op op)
309 case WINED3D_BLEND_OP_ADD:
310 return GL_FUNC_ADD_EXT;
311 case WINED3D_BLEND_OP_SUBTRACT:
312 return GL_FUNC_SUBTRACT_EXT;
313 case WINED3D_BLEND_OP_REVSUBTRACT:
314 return GL_FUNC_REVERSE_SUBTRACT_EXT;
315 case WINED3D_BLEND_OP_MIN:
317 case WINED3D_BLEND_OP_MAX:
320 FIXME("Unhandled blend op %#x.\n", op);
325 static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
327 const struct wined3d_gl_info *gl_info = context->gl_info;
328 GLenum blend_equation_alpha = GL_FUNC_ADD_EXT;
329 GLenum blend_equation = GL_FUNC_ADD_EXT;
331 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
332 if (state->render_states[WINED3D_RS_BLENDOPALPHA]
333 && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
335 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
339 blend_equation = gl_blend_op(state->render_states[WINED3D_RS_BLENDOP]);
340 blend_equation_alpha = gl_blend_op(state->render_states[WINED3D_RS_BLENDOPALPHA]);
341 TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
343 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
345 GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
346 checkGLcall("glBlendEquationSeparateEXT");
350 GL_EXTCALL(glBlendEquationEXT(blend_equation));
351 checkGLcall("glBlendEquation");
355 static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_format *dst_format)
359 case WINED3D_BLEND_ZERO:
361 case WINED3D_BLEND_ONE:
363 case WINED3D_BLEND_SRCCOLOR:
365 case WINED3D_BLEND_INVSRCCOLOR:
366 return GL_ONE_MINUS_SRC_COLOR;
367 case WINED3D_BLEND_SRCALPHA:
369 case WINED3D_BLEND_INVSRCALPHA:
370 return GL_ONE_MINUS_SRC_ALPHA;
371 case WINED3D_BLEND_DESTCOLOR:
373 case WINED3D_BLEND_INVDESTCOLOR:
374 return GL_ONE_MINUS_DST_COLOR;
375 /* To compensate for the lack of format switching with backbuffer
376 * offscreen rendering, and with onscreen rendering, we modify the
377 * alpha test parameters for (INV)DESTALPHA if the render target
378 * doesn't support alpha blending. A nonexistent alpha channel
379 * returns 1.0, so WINED3D_BLEND_DESTALPHA becomes GL_ONE, and
380 * WINED3D_BLEND_INVDESTALPHA becomes GL_ZERO. */
381 case WINED3D_BLEND_DESTALPHA:
382 return dst_format->alpha_size ? GL_DST_ALPHA : GL_ONE;
383 case WINED3D_BLEND_INVDESTALPHA:
384 return dst_format->alpha_size ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
385 case WINED3D_BLEND_SRCALPHASAT:
386 return GL_SRC_ALPHA_SATURATE;
387 case WINED3D_BLEND_BLENDFACTOR:
388 return GL_CONSTANT_COLOR_EXT;
389 case WINED3D_BLEND_INVBLENDFACTOR:
390 return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
392 FIXME("Unhandled blend factor %#x.\n", factor);
397 static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
399 const struct wined3d_surface *target = state->fb->render_targets[0];
400 const struct wined3d_gl_info *gl_info = context->gl_info;
401 GLenum srcBlend, dstBlend;
402 enum wined3d_blend d3d_blend;
404 /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
405 * blending parameters to work. */
406 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]
407 || state->render_states[WINED3D_RS_EDGEANTIALIAS]
408 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
410 /* Disable blending in all cases even without pixelshaders.
411 * With blending on we could face a big performance penalty.
412 * The d3d9 visual test confirms the behavior. */
413 if (context->render_offscreen
414 && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
416 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
417 checkGLcall("glDisable GL_BLEND");
422 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
423 checkGLcall("glEnable GL_BLEND");
428 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
429 checkGLcall("glDisable GL_BLEND");
430 /* Nothing more to do - get out */
434 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
435 * source blending values which are still valid up to d3d9. They should
436 * not occur as dest blend values. */
437 d3d_blend = state->render_states[WINED3D_RS_SRCBLEND];
438 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
440 srcBlend = GL_SRC_ALPHA;
441 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
443 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
445 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
446 dstBlend = GL_SRC_ALPHA;
450 srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
451 dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
452 target->resource.format);
455 if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
456 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
458 gl_info->gl_ops.gl.p_glEnable(GL_LINE_SMOOTH);
459 checkGLcall("glEnable(GL_LINE_SMOOTH)");
460 if (srcBlend != GL_SRC_ALPHA)
461 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param.\n");
462 if (dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE)
463 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param.\n");
467 gl_info->gl_ops.gl.p_glDisable(GL_LINE_SMOOTH);
468 checkGLcall("glDisable(GL_LINE_SMOOTH)");
471 /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
472 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP)))
473 state_blendop(context, state, STATE_RENDER(WINED3D_RS_BLENDOPALPHA));
475 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
477 GLenum srcBlendAlpha, dstBlendAlpha;
479 /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
480 if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
482 WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
486 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
487 * source blending values which are still valid up to d3d9. They should
488 * not occur as dest blend values. */
489 d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA];
490 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
492 srcBlendAlpha = GL_SRC_ALPHA;
493 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
495 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
497 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
498 dstBlendAlpha = GL_SRC_ALPHA;
502 srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
503 dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
504 target->resource.format);
507 GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
508 checkGLcall("glBlendFuncSeparateEXT");
512 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
513 gl_info->gl_ops.gl.p_glBlendFunc(srcBlend, dstBlend);
514 checkGLcall("glBlendFunc");
517 /* Colorkey fixup for stage 0 alphaop depends on
518 * WINED3D_RS_ALPHABLENDENABLE state, so it may need updating. */
519 if (state->render_states[WINED3D_RS_COLORKEYENABLE])
520 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
523 static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
525 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
528 static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
530 const struct wined3d_gl_info *gl_info = context->gl_info;
533 TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
535 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
536 GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
537 checkGLcall("glBlendColor");
540 static void state_alpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
542 const struct wined3d_gl_info *gl_info = context->gl_info;
545 BOOL enable_ckey = FALSE;
547 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
549 /* Find out if the texture on the first stage has a ckey set
550 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
551 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
552 * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
553 * in case it finds some texture+colorkeyenable combination which needs extra care.
555 if (state->textures[0])
557 struct wined3d_surface *surface = surface_from_resource(state->textures[0]->sub_resources[0]);
559 if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
563 if (enable_ckey || context->last_was_ckey)
564 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
565 context->last_was_ckey = enable_ckey;
567 if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
568 || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
570 gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST);
571 checkGLcall("glEnable GL_ALPHA_TEST");
575 gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
576 checkGLcall("glDisable GL_ALPHA_TEST");
577 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
583 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
585 glParm = GL_NOTEQUAL;
590 ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
591 glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
595 gl_info->gl_ops.gl.p_glAlphaFunc(glParm, ref);
596 checkGLcall("glAlphaFunc");
600 static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
602 context->load_constants = 1;
605 static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
607 const struct wined3d_gl_info *gl_info = context->gl_info;
608 DWORD enable = 0xffffffff;
609 DWORD disable = 0x00000000;
613 const struct wined3d_device *device = context->swapchain->device;
615 if (!device->vs_clipping)
617 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
618 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
619 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
620 * of that - don't do anything here and keep them disabled
622 if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
624 static BOOL warned = FALSE;
626 FIXME("Clipping not supported with vertex shaders\n");
633 /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
634 * hardcoded into the shader. Update the shader to update the enabled clipplanes */
635 context->select_shader = 1;
636 context->load_constants = 1;
639 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
640 * of already set values
643 /* If enabling / disabling all
644 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
646 if (state->render_states[WINED3D_RS_CLIPPING])
648 enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
649 disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
653 disable = 0xffffffff;
657 if (enable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE0);
658 if (enable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE1);
659 if (enable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE2);
660 if (enable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE3);
661 if (enable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE4);
662 if (enable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE5);
663 checkGLcall("clip plane enable");
665 if (disable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0);
666 if (disable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1);
667 if (disable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2);
668 if (disable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3);
669 if (disable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4);
670 if (disable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5);
671 checkGLcall("clip plane disable");
674 static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
676 const struct wined3d_gl_info *gl_info = context->gl_info;
677 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
678 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
679 * specular color. This is wrong:
680 * Separate specular color means the specular colour is maintained separately, whereas
681 * single color means it is merged in. However in both cases they are being used to
683 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
684 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
688 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
689 * Instead, we need to setup the FinalCombiner properly.
691 * The default setup for the FinalCombiner is:
693 * <variable> <input> <mapping> <usage>
694 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
695 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
696 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
697 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
698 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
699 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
700 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
702 * That's pretty much fine as it is, except for variable B, which needs to take
703 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
704 * whether WINED3D_RS_SPECULARENABLE is enabled or not.
707 TRACE("Setting specular enable state and materials\n");
708 if (state->render_states[WINED3D_RS_SPECULARENABLE])
710 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
711 checkGLcall("glMaterialfv");
713 if (state->material.power > gl_info->limits.shininess)
715 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
716 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
717 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
718 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
719 * them, it should be safe to do so without major visual distortions.
721 WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
722 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
726 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
728 checkGLcall("glMaterialf(GL_SHININESS)");
730 if (gl_info->supported[EXT_SECONDARY_COLOR])
731 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_SUM_EXT);
733 TRACE("Specular colors cannot be enabled in this version of opengl\n");
734 checkGLcall("glEnable(GL_COLOR_SUM)");
736 if (gl_info->supported[NV_REGISTER_COMBINERS])
738 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
739 checkGLcall("glFinalCombinerInputNV()");
742 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
744 /* for the case of enabled lighting: */
745 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
746 checkGLcall("glMaterialfv");
748 /* for the case of disabled lighting: */
749 if (gl_info->supported[EXT_SECONDARY_COLOR])
750 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
752 TRACE("Specular colors cannot be disabled in this version of opengl\n");
753 checkGLcall("glDisable(GL_COLOR_SUM)");
755 if (gl_info->supported[NV_REGISTER_COMBINERS])
757 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
758 checkGLcall("glFinalCombinerInputNV()");
762 TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
763 state->material.diffuse.r, state->material.diffuse.g,
764 state->material.diffuse.b, state->material.diffuse.a);
765 TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
766 state->material.ambient.r, state->material.ambient.g,
767 state->material.ambient.b, state->material.ambient.a);
768 TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
769 state->material.specular.r, state->material.specular.g,
770 state->material.specular.b, state->material.specular.a);
771 TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
772 state->material.emissive.r, state->material.emissive.g,
773 state->material.emissive.b, state->material.emissive.a);
775 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
776 checkGLcall("glMaterialfv(GL_AMBIENT)");
777 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
778 checkGLcall("glMaterialfv(GL_DIFFUSE)");
779 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
780 checkGLcall("glMaterialfv(GL_EMISSION)");
783 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
785 const struct wined3d_gl_info *gl_info = context->gl_info;
788 /* Note the texture color applies to all textures whereas
789 * GL_TEXTURE_ENV_COLOR applies to active only. */
791 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
793 /* And now the default texture color as well */
794 for (i = 0; i < gl_info->limits.texture_stages; ++i)
796 /* Note the WINED3D_RS value applies to all textures, but GL has one
797 * per texture, so apply it now ready to be used! */
798 context_active_texture(context, gl_info, i);
800 gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
801 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
805 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
806 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
808 const struct wined3d_gl_info *gl_info = context->gl_info;
810 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
811 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
812 GL_EXTCALL(glActiveStencilFaceEXT(face));
813 checkGLcall("glActiveStencilFaceEXT(...)");
814 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
815 checkGLcall("glStencilFunc(...)");
816 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
817 checkGLcall("glStencilOp(...)");
820 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
824 case WINED3D_STENCIL_OP_KEEP:
826 case WINED3D_STENCIL_OP_ZERO:
828 case WINED3D_STENCIL_OP_REPLACE:
830 case WINED3D_STENCIL_OP_INCR_SAT:
832 case WINED3D_STENCIL_OP_DECR_SAT:
834 case WINED3D_STENCIL_OP_INVERT:
836 case WINED3D_STENCIL_OP_INCR:
837 return GL_INCR_WRAP_EXT;
838 case WINED3D_STENCIL_OP_DECR:
839 return GL_DECR_WRAP_EXT;
841 FIXME("Unrecognized stencil op %#x.\n", op);
846 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
848 const struct wined3d_gl_info *gl_info = context->gl_info;
849 DWORD onesided_enable = FALSE;
850 DWORD twosided_enable = FALSE;
851 GLint func = GL_ALWAYS;
852 GLint func_ccw = GL_ALWAYS;
855 GLint stencilFail = GL_KEEP;
856 GLint depthFail = GL_KEEP;
857 GLint stencilPass = GL_KEEP;
858 GLint stencilFail_ccw = GL_KEEP;
859 GLint depthFail_ccw = GL_KEEP;
860 GLint stencilPass_ccw = GL_KEEP;
862 /* No stencil test without a stencil buffer. */
863 if (!state->fb->depth_stencil)
865 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
866 checkGLcall("glDisable GL_STENCIL_TEST");
870 onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
871 twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
872 if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
874 if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
875 func_ccw = GL_ALWAYS;
876 ref = state->render_states[WINED3D_RS_STENCILREF];
877 mask = state->render_states[WINED3D_RS_STENCILMASK];
878 stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
879 depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
880 stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
881 stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
882 depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
883 stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
885 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
886 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
887 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
888 onesided_enable, twosided_enable, ref, mask,
889 func, stencilFail, depthFail, stencilPass,
890 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
892 if (twosided_enable && onesided_enable)
894 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
895 checkGLcall("glEnable GL_STENCIL_TEST");
897 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
899 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
900 * which has an effect on the code below too. If we apply the front face
901 * afterwards, we are sure that the active stencil face is set to front,
902 * and other stencil functions which do not use two sided stencil do not have
905 renderstate_stencil_twosided(context, GL_BACK,
906 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
907 renderstate_stencil_twosided(context, GL_FRONT,
908 func, ref, mask, stencilFail, depthFail, stencilPass);
910 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
912 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
913 checkGLcall("glStencilFuncSeparateATI(...)");
914 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
915 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
916 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
917 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
919 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
922 else if(onesided_enable)
924 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
926 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
927 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
930 /* This code disables the ATI extension as well, since the standard stencil functions are equal
931 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
933 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
934 checkGLcall("glEnable GL_STENCIL_TEST");
935 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
936 checkGLcall("glStencilFunc(...)");
937 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
938 checkGLcall("glStencilOp(...)");
942 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
943 checkGLcall("glDisable GL_STENCIL_TEST");
947 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
949 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
950 const struct wined3d_gl_info *gl_info = context->gl_info;
952 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
953 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
954 gl_info->gl_ops.gl.p_glStencilMask(mask);
955 checkGLcall("glStencilMask");
956 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
957 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
958 gl_info->gl_ops.gl.p_glStencilMask(mask);
961 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
963 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
964 const struct wined3d_gl_info *gl_info = context->gl_info;
966 gl_info->gl_ops.gl.p_glStencilMask(mask);
967 checkGLcall("glStencilMask");
970 static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
972 const struct wined3d_gl_info *gl_info = context->gl_info;
974 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
976 if (!state->render_states[WINED3D_RS_FOGENABLE])
979 /* Table fog on: Never use fog coords, and use per-fragment fog */
980 if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
982 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST);
983 if (context->fog_coord)
985 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
986 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
987 context->fog_coord = FALSE;
990 /* Range fog is only used with per-vertex fog in d3d */
991 if (gl_info->supported[NV_FOG_DISTANCE])
993 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
994 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
999 /* Otherwise use per-vertex fog in any case */
1000 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_FASTEST);
1002 if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
1004 /* No fog at all, or transformed vertices: Use fog coord */
1005 if (!context->fog_coord)
1007 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1008 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
1009 context->fog_coord = TRUE;
1014 /* Otherwise, use the fragment depth */
1015 if (context->fog_coord)
1017 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1018 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1019 context->fog_coord = FALSE;
1022 if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
1024 if (gl_info->supported[NV_FOG_DISTANCE])
1026 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1027 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1031 WARN("Range fog enabled, but not supported by this GL implementation.\n");
1034 else if (gl_info->supported[NV_FOG_DISTANCE])
1036 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1037 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1042 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1044 const struct wined3d_gl_info *gl_info = context->gl_info;
1045 float fogstart, fogend;
1051 switch(context->fog_source) {
1057 case FOGSOURCE_COORD:
1063 tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
1064 fogstart = tmpvalue.f;
1065 tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
1066 fogend = tmpvalue.f;
1067 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
1068 if(fogstart == fogend) {
1069 fogstart = -INFINITY;
1075 /* This should not happen.context->fog_source is set in wined3d, not the app.
1076 * Still this is needed to make the compiler happy
1078 ERR("Unexpected fog coordinate source\n");
1083 gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, fogstart);
1084 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1085 TRACE("Fog Start == %f\n", fogstart);
1087 gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, fogend);
1088 checkGLcall("glFogf(GL_FOG_END, fogend)");
1089 TRACE("Fog End == %f\n", fogend);
1092 void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1094 const struct wined3d_gl_info *gl_info = context->gl_info;
1095 enum fogsource new_source;
1097 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
1099 if (!state->render_states[WINED3D_RS_FOGENABLE])
1101 /* No fog? Disable it, and we're done :-) */
1102 glDisableWINE(GL_FOG);
1103 checkGLcall("glDisable GL_FOG");
1109 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1110 * It can use the Z value of the vertex, or the alpha component of the specular color.
1111 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1112 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1113 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1115 * FOGTABLEMODE != NONE:
1116 * The Z value is used, with the equation specified, no matter what vertex type.
1118 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1119 * Per vertex fog is calculated using the specified fog equation and the parameters
1121 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1122 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1123 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1126 * Rules for vertex fog with shaders:
1128 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1129 * the fog computation to happen during transformation while openGL expects it to happen
1130 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1131 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1132 * To solve this problem, WineD3D does:
1133 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1135 * and 2) disables the fog computation (in either the fixed function or programmable
1136 * rasterizer) if using a vertex program.
1138 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1139 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1140 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1141 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1142 * There are some GL differences between specular fog coords and vertex shaders though.
1144 * With table fog the vertex shader fog coordinate is ignored.
1146 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1150 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1151 * the system will apply only pixel(=table) fog effects."
1153 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
1157 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1158 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1159 new_source = FOGSOURCE_VS;
1163 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
1165 /* If processed vertices are used, fall through to the NONE case */
1166 case WINED3D_FOG_EXP:
1167 if (!context->last_was_rhw)
1169 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1170 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1171 new_source = FOGSOURCE_FFP;
1176 case WINED3D_FOG_EXP2:
1177 if (!context->last_was_rhw)
1179 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1180 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1181 new_source = FOGSOURCE_FFP;
1186 case WINED3D_FOG_LINEAR:
1187 if (!context->last_was_rhw)
1189 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1190 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1191 new_source = FOGSOURCE_FFP;
1196 case WINED3D_FOG_NONE:
1197 /* Both are none? According to msdn the alpha channel of the specular
1198 * color contains a fog factor. Set it in drawStridedSlow.
1199 * Same happens with Vertexfog on transformed vertices
1201 new_source = FOGSOURCE_COORD;
1202 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1203 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1207 FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
1208 state->render_states[WINED3D_RS_FOGVERTEXMODE]);
1209 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1213 new_source = FOGSOURCE_FFP;
1215 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
1217 case WINED3D_FOG_EXP:
1218 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1219 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1222 case WINED3D_FOG_EXP2:
1223 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1224 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1227 case WINED3D_FOG_LINEAR:
1228 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1229 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1232 case WINED3D_FOG_NONE: /* Won't happen */
1234 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
1235 state->render_states[WINED3D_RS_FOGTABLEMODE]);
1239 glEnableWINE(GL_FOG);
1240 checkGLcall("glEnable GL_FOG");
1241 if (new_source != context->fog_source)
1243 context->fog_source = new_source;
1244 state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
1248 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1250 const struct wined3d_gl_info *gl_info = context->gl_info;
1253 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
1254 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, &col[0]);
1255 checkGLcall("glFog GL_FOG_COLOR");
1258 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1260 const struct wined3d_gl_info *gl_info = context->gl_info;
1266 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1267 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1268 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1271 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1273 const struct wined3d_device *device = context->swapchain->device;
1274 const struct wined3d_gl_info *gl_info = context->gl_info;
1277 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1278 * The vertex declaration will call this function if the fixed function pipeline is used.
1281 if(isStateDirty(context, STATE_VDECL)) {
1285 context->num_untracked_materials = 0;
1286 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1287 && state->render_states[WINED3D_RS_COLORVERTEX])
1289 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1290 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
1291 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
1292 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
1293 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
1295 if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1297 if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1298 Parm = GL_AMBIENT_AND_DIFFUSE;
1301 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1303 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1304 context->num_untracked_materials++;
1306 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1308 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1309 context->num_untracked_materials++;
1312 else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1315 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1317 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1318 context->num_untracked_materials++;
1320 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1322 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1323 context->num_untracked_materials++;
1326 else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1329 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1331 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1332 context->num_untracked_materials++;
1335 else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1341 /* Nothing changed, return. */
1342 if (Parm == context->tracking_parm) return;
1346 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_MATERIAL);
1347 checkGLcall("glDisable GL_COLOR_MATERIAL");
1351 gl_info->gl_ops.gl.p_glColorMaterial(GL_FRONT_AND_BACK, Parm);
1352 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1353 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_MATERIAL);
1354 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1357 /* Apparently calls to glMaterialfv are ignored for properties we're
1358 * tracking with glColorMaterial, so apply those here. */
1359 switch (context->tracking_parm)
1361 case GL_AMBIENT_AND_DIFFUSE:
1362 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1363 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1364 checkGLcall("glMaterialfv");
1368 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1369 checkGLcall("glMaterialfv");
1373 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1374 checkGLcall("glMaterialfv");
1378 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
1379 checkGLcall("glMaterialfv");
1383 /* Only change material color if specular is enabled, otherwise it is set to black */
1384 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1386 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
1387 checkGLcall("glMaterialfv");
1391 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1392 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1393 checkGLcall("glMaterialfv");
1398 context->tracking_parm = Parm;
1401 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1403 const struct wined3d_gl_info *gl_info = context->gl_info;
1407 struct wined3d_line_pattern lp;
1409 tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
1411 TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1413 if (tmppattern.lp.repeat_factor)
1415 gl_info->gl_ops.gl.p_glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1416 checkGLcall("glLineStipple(repeat, linepattern)");
1417 gl_info->gl_ops.gl.p_glEnable(GL_LINE_STIPPLE);
1418 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1422 gl_info->gl_ops.gl.p_glDisable(GL_LINE_STIPPLE);
1423 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1427 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1429 const struct wined3d_gl_info *gl_info = context->gl_info;
1431 if (isStateDirty(context, STATE_VDECL))
1434 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1435 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1436 * by zero and is not properly defined in opengl, so avoid it
1438 if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
1439 && (context->swapchain->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1441 gl_info->gl_ops.gl.p_glEnable(GL_NORMALIZE);
1442 checkGLcall("glEnable(GL_NORMALIZE);");
1446 gl_info->gl_ops.gl.p_glDisable(GL_NORMALIZE);
1447 checkGLcall("glDisable(GL_NORMALIZE);");
1451 static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1458 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1459 if (tmpvalue.f != 1.0f)
1461 FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1463 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1464 if (tmpvalue.f != 64.0f)
1466 FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1471 static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1473 const struct wined3d_gl_info *gl_info = context->gl_info;
1480 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1481 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1483 /* Max point size trumps min point size */
1488 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1489 checkGLcall("glPointParameterfEXT(...)");
1490 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1491 checkGLcall("glPointParameterfEXT(...)");
1494 static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1496 const struct wined3d_gl_info *gl_info = context->gl_info;
1503 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1504 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1506 /* Max point size trumps min point size */
1511 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1512 checkGLcall("glPointParameterfARB(...)");
1513 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1514 checkGLcall("glPointParameterfARB(...)");
1517 static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1519 const struct wined3d_gl_info *gl_info = context->gl_info;
1520 /* TODO: Group this with the viewport */
1522 * POINTSCALEENABLE controls how point size value is treated. If set to
1523 * true, the point size is scaled with respect to height of viewport.
1524 * When set to false point size is in pixels.
1527 /* Default values */
1528 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1532 } pointSize, A, B, C;
1534 pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
1535 A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
1536 B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
1537 C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
1539 if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1541 DWORD h = state->viewport.height;
1542 GLfloat scaleFactor;
1544 if (pointSize.f < gl_info->limits.pointsize_min)
1546 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1547 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1548 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1549 * are less than 1.0f. scale_factor = 1.0f / point_size.
1551 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1552 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1553 * is 1.0, but then accepts points below that and draws too small points
1555 pointSize.f = gl_info->limits.pointsize_min;
1557 else if(pointSize.f > gl_info->limits.pointsize_max)
1559 /* gl already scales the input to glPointSize,
1560 * d3d scales the result after the point size scale.
1561 * If the point size is bigger than the max size, use the
1562 * scaling to scale it bigger, and set the gl point size to max
1564 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1565 TRACE("scale: %f\n", scaleFactor);
1566 pointSize.f = gl_info->limits.pointsize_max;
1570 scaleFactor = powf(h * scaleFactor, 2);
1572 att[0] = A.f / scaleFactor;
1573 att[1] = B.f / scaleFactor;
1574 att[2] = C.f / scaleFactor;
1577 if (gl_info->supported[ARB_POINT_PARAMETERS])
1579 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1580 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1582 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1584 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1585 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1587 else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1589 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1592 gl_info->gl_ops.gl.p_glPointSize(pointSize.f);
1593 checkGLcall("glPointSize(...);");
1596 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1598 WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
1601 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1603 DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
1604 DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
1605 DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
1606 DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
1607 const struct wined3d_gl_info *gl_info = context->gl_info;
1609 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1610 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1611 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1612 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1613 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1614 gl_info->gl_ops.gl.p_glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1615 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1616 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1617 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1618 checkGLcall("glColorMask(...)");
1620 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1621 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1623 FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1624 mask0, mask1, mask2, mask3);
1625 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1629 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1631 GL_EXTCALL(glColorMaskIndexedEXT(index,
1632 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1633 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1634 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1635 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1638 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1640 set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
1643 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1645 set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
1648 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1650 set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
1653 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1655 set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
1658 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1660 const struct wined3d_gl_info *gl_info = context->gl_info;
1662 if (state->render_states[WINED3D_RS_LOCALVIEWER])
1664 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1665 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1669 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1670 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1674 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1676 if (state->render_states[WINED3D_RS_LASTPIXEL])
1678 TRACE("Last Pixel Drawing Enabled\n");
1684 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1687 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1692 static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1696 /* TODO: NV_POINT_SPRITE */
1697 if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1699 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1700 FIXME("Point sprites not supported\n");
1705 static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1707 const struct wined3d_gl_info *gl_info = context->gl_info;
1709 if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1711 gl_info->gl_ops.gl.p_glEnable(GL_POINT_SPRITE_ARB);
1712 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1716 gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
1717 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1721 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1723 if (state->render_states[WINED3D_RS_WRAP0]
1724 || state->render_states[WINED3D_RS_WRAP1]
1725 || state->render_states[WINED3D_RS_WRAP2]
1726 || state->render_states[WINED3D_RS_WRAP3]
1727 || state->render_states[WINED3D_RS_WRAP4]
1728 || state->render_states[WINED3D_RS_WRAP5]
1729 || state->render_states[WINED3D_RS_WRAP6]
1730 || state->render_states[WINED3D_RS_WRAP7]
1731 || state->render_states[WINED3D_RS_WRAP8]
1732 || state->render_states[WINED3D_RS_WRAP9]
1733 || state->render_states[WINED3D_RS_WRAP10]
1734 || state->render_states[WINED3D_RS_WRAP11]
1735 || state->render_states[WINED3D_RS_WRAP12]
1736 || state->render_states[WINED3D_RS_WRAP13]
1737 || state->render_states[WINED3D_RS_WRAP14]
1738 || state->render_states[WINED3D_RS_WRAP15])
1739 FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
1742 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1744 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1745 WARN("Multisample antialiasing not supported by GL.\n");
1748 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1750 const struct wined3d_gl_info *gl_info = context->gl_info;
1752 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1754 gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE_ARB);
1755 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1759 gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE_ARB);
1760 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1764 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1766 const struct wined3d_gl_info *gl_info = context->gl_info;
1768 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
1770 gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST);
1771 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1775 gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
1776 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1780 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1781 * OpenGL the bias is specified in units of "the smallest value that is
1782 * guaranteed to produce a resolvable offset for a given implementation". To
1783 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1784 * There's no practical way to retrieve that value from a given GL
1785 * implementation, but the D3D application has essentially the same problem,
1786 * which makes a guess of the depth buffer format's highest possible value a
1787 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1788 * depth slope, and doesn't need to be scaled. */
1789 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1791 const struct wined3d_gl_info *gl_info = context->gl_info;
1793 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
1794 || state->render_states[WINED3D_RS_DEPTHBIAS])
1796 const struct wined3d_surface *depth = state->fb->depth_stencil;
1803 } scale_bias, const_bias;
1805 scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
1806 const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
1808 gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL);
1809 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1811 if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
1813 float bias = -(float)const_bias.d;
1814 gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias);
1815 checkGLcall("glPolygonOffset");
1821 const struct wined3d_format *fmt = depth->resource.format;
1822 scale = powf(2, fmt->depth_size) - 1;
1823 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
1824 debug_d3dformat(fmt->id), scale);
1828 /* The context manager will reapply this state on a depth stencil change */
1829 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
1833 gl_info->gl_ops.gl.p_glPolygonOffset(scale_bias.f, const_bias.f * scale);
1834 checkGLcall("glPolygonOffset(...)");
1839 gl_info->gl_ops.gl.p_glDisable(GL_POLYGON_OFFSET_FILL);
1840 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1844 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1846 if (state->render_states[WINED3D_RS_ZVISIBLE])
1847 FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
1850 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1852 const struct wined3d_gl_info *gl_info = context->gl_info;
1854 if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
1856 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1857 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1861 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1862 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1866 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1868 if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
1869 FIXME("Stippled Alpha not supported yet.\n");
1872 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1874 if (state->render_states[WINED3D_RS_ANTIALIAS])
1875 FIXME("Antialias not supported yet.\n");
1878 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1880 if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
1881 FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
1882 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
1885 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1887 if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
1888 FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
1889 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
1892 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1900 if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
1902 static BOOL displayed = FALSE;
1904 tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
1906 FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1912 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1914 if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
1915 FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
1916 state->render_states[WINED3D_RS_POSITIONDEGREE]);
1919 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1921 if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
1922 FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
1923 state->render_states[WINED3D_RS_NORMALDEGREE]);
1926 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1928 if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
1929 FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1930 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
1933 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1940 const struct wined3d_gl_info *gl_info = context->gl_info;
1942 if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1944 zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
1945 zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
1947 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1948 * In d3d9 test is not performed in this case*/
1949 if (zmin.f <= zmax.f)
1951 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1952 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1953 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1954 checkGLcall("glDepthBoundsEXT(...)");
1958 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1959 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1964 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1965 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1968 state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
1971 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1973 if (state->render_states[WINED3D_RS_WRAPU])
1974 FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
1977 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1979 if (state->render_states[WINED3D_RS_WRAPV])
1980 FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
1983 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1985 if (state->render_states[WINED3D_RS_MONOENABLE])
1986 FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
1989 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1991 if (state->render_states[WINED3D_RS_ROP2])
1992 FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
1995 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1997 if (state->render_states[WINED3D_RS_PLANEMASK])
1998 FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
2001 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2003 if (state->render_states[WINED3D_RS_SUBPIXEL])
2004 FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
2007 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2009 if (state->render_states[WINED3D_RS_SUBPIXELX])
2010 FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
2013 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2015 if (state->render_states[WINED3D_RS_STIPPLEENABLE])
2016 FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
2019 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2021 if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
2022 FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
2025 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2027 if (state->render_states[WINED3D_RS_ANISOTROPY])
2028 FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
2031 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2033 if (state->render_states[WINED3D_RS_FLUSHBATCH])
2034 FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
2037 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2039 if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
2040 FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
2043 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2045 if (state->render_states[WINED3D_RS_EXTENTS])
2046 FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
2049 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2051 if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
2052 FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
2055 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2057 if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
2058 FIXME("Software vertex processing not implemented.\n");
2061 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2062 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2063 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2064 * flag specifies the complement of the input should be used. */
2065 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2066 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2068 /* Calculate the operand */
2070 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2071 else *operand = GL_ONE_MINUS_SRC_COLOR;
2073 if (from_alpha) *operand = GL_SRC_ALPHA;
2074 else *operand = GL_SRC_COLOR;
2077 /* Calculate the source */
2078 switch (arg & WINED3DTA_SELECTMASK) {
2079 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2080 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2081 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2082 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2083 case WINED3DTA_SPECULAR:
2085 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2086 * 'Secondary color' and isn't supported until base GL supports it
2087 * There is no concept of temp registers as far as I can tell
2089 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2090 *source = GL_TEXTURE;
2093 FIXME("Unrecognized texture arg %#x\n", arg);
2094 *source = GL_TEXTURE;
2099 /* Setup the texture operations texture stage states */
2100 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2101 BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2103 GLenum src1, src2, src3;
2104 GLenum opr1, opr2, opr3;
2106 GLenum src0_target, src1_target, src2_target;
2107 GLenum opr0_target, opr1_target, opr2_target;
2109 GLenum opr=0, invopr, src3_target, opr3_target;
2110 BOOL Handled = FALSE;
2112 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2114 /* This is called by a state handler which has the gl lock held and a context for the thread */
2116 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2117 the form (a1 <operation> a2). However, some of the more complex operations
2118 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2119 in a third parameter called a0. Therefore these are operations of the form
2120 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2122 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2123 functions below, expect their syntax to differ slightly to those listed in the
2124 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2125 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2129 comb_target = GL_COMBINE_ALPHA;
2130 src0_target = GL_SOURCE0_ALPHA;
2131 src1_target = GL_SOURCE1_ALPHA;
2132 src2_target = GL_SOURCE2_ALPHA;
2133 opr0_target = GL_OPERAND0_ALPHA;
2134 opr1_target = GL_OPERAND1_ALPHA;
2135 opr2_target = GL_OPERAND2_ALPHA;
2136 scal_target = GL_ALPHA_SCALE;
2140 comb_target = GL_COMBINE_RGB;
2141 src0_target = GL_SOURCE0_RGB;
2142 src1_target = GL_SOURCE1_RGB;
2143 src2_target = GL_SOURCE2_RGB;
2144 opr0_target = GL_OPERAND0_RGB;
2145 opr1_target = GL_OPERAND1_RGB;
2146 opr2_target = GL_OPERAND2_RGB;
2147 scal_target = GL_RGB_SCALE;
2150 /* If a texture stage references an invalid texture unit the stage just
2151 * passes through the result from the previous stage */
2152 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2154 arg1 = WINED3DTA_CURRENT;
2155 op = WINED3D_TOP_SELECT_ARG1;
2158 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2160 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2162 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2164 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2165 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2167 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2169 Handled = TRUE; /* Assume will be handled */
2171 /* Other texture operations require special extensions: */
2172 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2176 invopr = GL_ONE_MINUS_SRC_ALPHA;
2177 src3_target = GL_SOURCE3_ALPHA_NV;
2178 opr3_target = GL_OPERAND3_ALPHA_NV;
2181 invopr = GL_ONE_MINUS_SRC_COLOR;
2182 src3_target = GL_SOURCE3_RGB_NV;
2183 opr3_target = GL_OPERAND3_RGB_NV;
2187 case WINED3D_TOP_DISABLE: /* Only for alpha */
2188 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2189 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2190 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2191 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2192 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2193 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2194 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2195 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2196 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2197 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2198 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2199 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2200 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2201 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2202 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2203 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2204 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2205 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2208 case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
2209 case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
2210 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2211 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2212 if (op == WINED3D_TOP_SELECT_ARG1)
2214 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2215 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2216 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2217 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2221 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2222 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2223 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2224 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2226 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2227 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2228 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2229 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2230 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2231 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2232 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2233 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2234 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2235 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2236 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2237 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2240 case WINED3D_TOP_MODULATE:
2241 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2242 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2243 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2244 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2245 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2246 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2247 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2248 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2249 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2250 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2251 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2252 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2253 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2254 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2255 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2256 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2257 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2258 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2259 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2260 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2262 case WINED3D_TOP_MODULATE_2X:
2263 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2264 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2265 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2266 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2267 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2268 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2269 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2270 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2271 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2272 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2273 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2274 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2275 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2276 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2277 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2278 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2279 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2280 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2281 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2282 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2284 case WINED3D_TOP_MODULATE_4X:
2285 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2286 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2287 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2288 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2289 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2290 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2291 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2292 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2293 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2294 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2295 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2296 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2297 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2298 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2299 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2300 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2301 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2302 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2303 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2304 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2307 case WINED3D_TOP_ADD:
2308 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2309 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2310 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2311 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2312 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2313 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2314 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2315 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2316 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2317 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2318 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2319 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2320 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2321 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2322 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2323 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2324 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2325 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2326 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2327 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2330 case WINED3D_TOP_ADD_SIGNED:
2331 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2332 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2333 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2334 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2335 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2336 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2337 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2338 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2339 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2340 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2341 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2342 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2343 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2344 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2345 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2346 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2347 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2348 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2349 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2350 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2353 case WINED3D_TOP_ADD_SIGNED_2X:
2354 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2355 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2356 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2357 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2358 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2359 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2360 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2361 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2362 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2363 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2364 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2365 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2366 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2367 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2368 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2369 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2370 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2371 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2372 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2373 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2376 case WINED3D_TOP_ADD_SMOOTH:
2377 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2378 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2379 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2380 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2381 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2382 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2383 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2384 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2385 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2386 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2387 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2388 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2389 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2390 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2391 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2392 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2394 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2395 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2396 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2397 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2399 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2400 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2401 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2402 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2405 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2406 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2407 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2408 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2409 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2410 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2411 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2412 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
2413 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
2414 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2415 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2416 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2417 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2418 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2419 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2420 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
2421 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
2422 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2423 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2424 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2425 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2427 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2428 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2429 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2430 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2431 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2432 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2433 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2434 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2435 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2436 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2437 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2438 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2439 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2440 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2441 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2442 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2443 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2444 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2445 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2446 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2447 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2449 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2450 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2451 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2452 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2453 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2454 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2455 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2456 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
2457 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
2458 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2459 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2460 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2461 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2462 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2463 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2464 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
2465 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
2466 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2467 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2468 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2469 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2471 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2472 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2473 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2474 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2475 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2476 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2477 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2478 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2479 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2480 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2481 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2482 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2483 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2484 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2485 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2486 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2487 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2488 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2489 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2490 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2491 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2493 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2494 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2495 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2496 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2497 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2498 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2499 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2500 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2501 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2502 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2503 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2504 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2505 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2506 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2507 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2508 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2509 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2511 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2512 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2514 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2515 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2516 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2517 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2519 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2520 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2521 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2522 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2523 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2524 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2525 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2526 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2527 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2528 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2529 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2530 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2531 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2533 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2534 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2536 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2537 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2538 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2539 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2540 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2541 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2542 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2543 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2545 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2546 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2547 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2548 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2549 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2550 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2551 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2552 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2553 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2554 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2555 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2556 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2557 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2558 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2559 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2560 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2561 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2563 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2564 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2565 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2566 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2568 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2569 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2570 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2571 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2573 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2574 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2575 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2576 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2577 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2579 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2580 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2581 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2582 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2584 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2585 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2586 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2587 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2588 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2589 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2590 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2591 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2593 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2594 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2596 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2597 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2598 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2599 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2600 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2601 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2602 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2603 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2605 case WINED3D_TOP_MULTIPLY_ADD:
2606 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2607 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2608 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2609 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2610 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2611 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2612 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2613 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2614 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2615 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2616 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2617 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2618 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2619 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2620 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2621 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2622 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2623 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2624 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2625 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2628 case WINED3D_TOP_BUMPENVMAP:
2629 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
2630 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2639 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2640 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2644 } /* GL_NV_texture_env_combine4 */
2646 Handled = TRUE; /* Again, assume handled */
2648 case WINED3D_TOP_DISABLE: /* Only for alpha */
2649 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2650 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2651 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2652 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2653 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2654 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2655 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2656 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2658 case WINED3D_TOP_SELECT_ARG1:
2659 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2660 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2661 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2662 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2663 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2664 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2665 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2666 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2668 case WINED3D_TOP_SELECT_ARG2:
2669 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2670 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2671 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2672 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2673 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2674 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2675 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2676 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2678 case WINED3D_TOP_MODULATE:
2679 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2680 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2681 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2682 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2683 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2684 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2685 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2686 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2687 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2688 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2689 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2690 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2692 case WINED3D_TOP_MODULATE_2X:
2693 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2694 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2695 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2696 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2697 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2698 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2699 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2700 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2701 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2702 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2703 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2704 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2706 case WINED3D_TOP_MODULATE_4X:
2707 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2708 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2709 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2710 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2711 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2712 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2713 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2714 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2715 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2716 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2717 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2718 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2720 case WINED3D_TOP_ADD:
2721 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2722 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2723 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2724 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2725 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2726 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2727 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2728 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2729 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2730 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2731 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2732 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2734 case WINED3D_TOP_ADD_SIGNED:
2735 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2736 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2737 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2738 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2739 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2740 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2741 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2742 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2743 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2744 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2745 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2746 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2748 case WINED3D_TOP_ADD_SIGNED_2X:
2749 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2750 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2751 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2752 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2753 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2754 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2755 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2756 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2757 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2758 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2759 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2760 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2762 case WINED3D_TOP_SUBTRACT:
2763 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2765 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2766 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2767 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2768 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2769 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2770 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2771 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2772 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2773 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2774 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2775 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2776 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2778 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2782 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2783 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2784 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2785 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2786 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2787 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2788 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2789 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2790 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2791 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2792 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2793 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
2794 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2795 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2796 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2797 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2798 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2800 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2801 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2802 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2803 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2804 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2805 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2806 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2807 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2808 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2809 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2810 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2811 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2812 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2813 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2814 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2815 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2816 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2818 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2819 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2820 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2821 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2822 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2823 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2824 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2825 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2826 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2827 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2828 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2829 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
2830 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2831 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2832 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2833 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2834 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2836 case WINED3D_TOP_BLEND_CURRENT_ALPHA:
2837 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2838 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2839 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2840 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2841 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2842 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2843 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2844 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2845 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2846 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2847 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
2848 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2849 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2850 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2851 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2852 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2854 case WINED3D_TOP_DOTPRODUCT3:
2855 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2857 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2858 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2860 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2862 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2863 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2865 FIXME("This version of opengl does not support GL_DOT3\n");
2867 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2868 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2869 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2870 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2871 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2872 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2873 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2874 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2875 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2876 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2878 case WINED3D_TOP_LERP:
2879 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2880 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2881 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2882 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2883 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2884 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2885 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2886 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2887 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2888 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2889 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2890 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2891 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2892 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2893 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2894 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2896 case WINED3D_TOP_ADD_SMOOTH:
2897 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2899 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2900 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2901 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2902 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2904 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2905 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2906 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2907 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2909 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2910 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2911 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2912 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2913 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2914 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2915 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2916 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2917 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2918 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2919 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2920 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2924 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2925 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2927 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2928 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2929 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2930 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2931 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2932 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2933 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2934 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2935 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2936 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2937 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2938 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2939 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2940 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2941 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2942 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2946 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2947 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2949 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2950 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2951 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2952 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2954 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2955 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2956 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2957 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2959 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2960 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2961 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2962 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2963 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2964 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2965 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2966 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2967 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2968 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2969 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2970 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2974 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2975 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2977 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2978 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2979 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2980 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2981 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2982 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2983 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2984 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2986 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2987 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2988 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2989 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2991 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2992 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2993 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2994 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2995 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2996 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2997 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2998 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3002 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3003 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3005 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3006 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3007 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3008 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3010 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3011 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3012 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3013 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3015 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3016 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3017 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3018 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3019 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
3020 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
3021 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3022 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3023 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3024 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3025 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3026 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3030 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3031 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3033 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3034 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3035 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3036 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3038 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
3039 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
3040 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3041 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3043 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3044 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3045 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3046 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3048 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3049 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3050 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3051 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3053 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
3054 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
3055 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3056 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3057 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3058 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3059 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3060 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3064 case WINED3D_TOP_MULTIPLY_ADD:
3065 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3067 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3068 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3069 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3070 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3071 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3072 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3073 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3074 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3075 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3076 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3077 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3078 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3079 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3080 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3081 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3082 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3086 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3087 case WINED3D_TOP_BUMPENVMAP:
3088 if (gl_info->supported[NV_TEXTURE_SHADER2])
3090 /* Technically texture shader support without register combiners is possible, but not expected to occur
3091 * on real world cards, so for now a fixme should be enough
3093 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3103 BOOL combineOK = TRUE;
3104 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3109 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3111 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3113 /* Note: If COMBINE4 in effect can't go back to combine! */
3116 case WINED3D_TOP_ADD_SMOOTH:
3117 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3118 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3119 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3120 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3121 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3122 case WINED3D_TOP_MULTIPLY_ADD:
3123 /* Ignore those implemented in both cases */
3126 case WINED3D_TOP_SELECT_ARG1:
3127 case WINED3D_TOP_SELECT_ARG2:
3132 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3140 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3141 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3147 /* After all the extensions, if still unhandled, report fixme */
3148 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3152 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3154 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3155 const struct wined3d_device *device = context->swapchain->device;
3156 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3157 DWORD mapped_stage = device->texUnitMap[stage];
3158 const struct wined3d_gl_info *gl_info = context->gl_info;
3160 TRACE("Setting color op for stage %d\n", stage);
3162 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3163 if (use_ps(state)) return;
3165 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3167 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3169 if (tex_used && mapped_stage >= gl_info->limits.textures)
3171 FIXME("Attempt to enable unsupported stage!\n");
3174 context_active_texture(context, gl_info, mapped_stage);
3177 if (stage >= state->lowest_disabled_stage)
3179 TRACE("Stage disabled\n");
3180 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3182 /* Disable everything here */
3183 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3184 checkGLcall("glDisable(GL_TEXTURE_2D)");
3185 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3186 checkGLcall("glDisable(GL_TEXTURE_3D)");
3187 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3189 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3190 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3192 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3194 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3195 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3202 /* The sampler will also activate the correct texture dimensions, so no
3203 * need to do it here if the sampler for this stage is dirty. */
3204 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3205 texture_activate_dimensions(state->textures[stage], gl_info);
3207 set_tex_op(gl_info, state, FALSE, stage,
3208 state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3209 state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3210 state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3211 state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3214 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3216 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3217 const struct wined3d_device *device = context->swapchain->device;
3218 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3219 DWORD mapped_stage = device->texUnitMap[stage];
3220 const struct wined3d_gl_info *gl_info = context->gl_info;
3221 DWORD op, arg1, arg2, arg0;
3223 TRACE("Setting alpha op for stage %d\n", stage);
3224 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3225 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3227 if (tex_used && mapped_stage >= gl_info->limits.textures)
3229 FIXME("Attempt to enable unsupported stage!\n");
3232 context_active_texture(context, gl_info, mapped_stage);
3235 op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3236 arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3237 arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3238 arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3240 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3242 struct wined3d_texture *texture = state->textures[0];
3243 GLenum texture_dimensions = texture->target;
3245 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3247 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3249 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3251 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3252 * properly. On the other hand applications can still use texture combiners apparently. This code
3253 * takes care that apps cannot remove the texture's alpha channel entirely.
3255 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3256 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3257 * and alpha component of diffuse color to draw things like translucent text and perform other
3260 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3261 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3262 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3263 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3264 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3265 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3266 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3267 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3268 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3271 * What to do with multitexturing? So far no app has been found that uses color keying with
3273 if (op == WINED3D_TOP_DISABLE)
3275 arg1 = WINED3DTA_TEXTURE;
3276 op = WINED3D_TOP_SELECT_ARG1;
3278 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3280 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3282 arg2 = WINED3DTA_TEXTURE;
3283 op = WINED3D_TOP_MODULATE;
3285 else arg1 = WINED3DTA_TEXTURE;
3287 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3289 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3291 arg1 = WINED3DTA_TEXTURE;
3292 op = WINED3D_TOP_MODULATE;
3294 else arg2 = WINED3DTA_TEXTURE;
3300 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3301 * this if block here, and the other code(color keying, texture unit selection) are the same
3303 TRACE("Setting alpha op for stage %d\n", stage);
3304 if (gl_info->supported[NV_REGISTER_COMBINERS])
3306 set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3307 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3311 set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3315 static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3317 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3318 const struct wined3d_device *device = context->swapchain->device;
3319 const struct wined3d_gl_info *gl_info = context->gl_info;
3320 DWORD mapped_stage = device->texUnitMap[texUnit];
3324 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3325 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3327 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3331 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3332 if (mapped_stage >= gl_info->limits.textures) return;
3334 context_active_texture(context, gl_info, mapped_stage);
3335 generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3336 coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3338 set_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3339 state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3340 generated, context->last_was_rhw,
3341 device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3342 ? device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3343 : WINED3DFMT_UNKNOWN,
3344 device->shader_backend->shader_has_ffp_proj_control(device->shader_priv));
3346 /* The sampler applying function calls us if this changes */
3347 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3350 FIXME("Non-power2 texture being used with generated texture coords\n");
3352 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3353 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3356 TRACE("Non power two matrix multiply fixup\n");
3357 gl_info->gl_ops.gl.p_glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3362 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3364 unsigned int texture_idx;
3366 for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3368 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3369 gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3373 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3374 GLuint *curVBO, const struct wined3d_state *state)
3376 const struct wined3d_device *device = context->swapchain->device;
3377 const struct wined3d_gl_info *gl_info = context->gl_info;
3378 unsigned int mapped_stage = 0;
3379 unsigned int textureNo = 0;
3381 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3383 int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3385 mapped_stage = device->texUnitMap[textureNo];
3386 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3388 if (mapped_stage >= gl_info->limits.texture_coords)
3390 FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3394 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3396 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3398 TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3399 textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3401 if (*curVBO != e->data.buffer_object)
3403 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3404 checkGLcall("glBindBufferARB");
3405 *curVBO = e->data.buffer_object;
3408 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3409 checkGLcall("glClientActiveTextureARB");
3411 /* The coords to supply depend completely on the fvf / vertex shader */
3412 gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3413 e->data.addr + state->load_base_vertex_index * e->stride);
3414 gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3418 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3421 if (gl_info->supported[NV_REGISTER_COMBINERS])
3423 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3424 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3426 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3430 checkGLcall("loadTexCoords");
3433 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3435 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3436 const struct wined3d_device *device = context->swapchain->device;
3437 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3438 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3439 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3440 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3441 const struct wined3d_gl_info *gl_info = context->gl_info;
3442 DWORD mapped_stage = device->texUnitMap[stage];
3444 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3446 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3450 if (mapped_stage >= gl_info->limits.fragment_samplers)
3452 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3455 context_active_texture(context, gl_info, mapped_stage);
3457 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3459 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3460 * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3461 * means use the vertex position (camera-space) as the input texture coordinates
3462 * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3463 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3464 * to the TEXCOORDINDEX value
3466 switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3468 case WINED3DTSS_TCI_PASSTHRU:
3469 /* Use the specified texture coordinates contained within the
3470 * vertex format. This value resolves to zero. */
3471 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3472 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3473 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3474 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3475 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3478 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3479 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3480 * as the input texture coordinates for this stage's texture transformation. This
3481 * equates roughly to EYE_LINEAR */
3483 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3484 gl_info->gl_ops.gl.p_glPushMatrix();
3485 gl_info->gl_ops.gl.p_glLoadIdentity();
3486 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3487 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3488 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3489 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3490 gl_info->gl_ops.gl.p_glPopMatrix();
3491 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3493 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3494 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3495 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3496 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3498 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3499 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3500 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3501 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3505 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3506 /* Note that NV_TEXGEN_REFLECTION support is implied when
3507 * ARB_TEXTURE_CUBE_MAP is supported */
3508 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3510 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3514 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3515 gl_info->gl_ops.gl.p_glPushMatrix();
3516 gl_info->gl_ops.gl.p_glLoadIdentity();
3517 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3518 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3519 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3520 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3521 gl_info->gl_ops.gl.p_glPopMatrix();
3522 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3524 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3525 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3526 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3527 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3529 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3530 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3531 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3532 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3536 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3537 /* Note that NV_TEXGEN_REFLECTION support is implied when
3538 * ARB_TEXTURE_CUBE_MAP is supported */
3539 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3541 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3545 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3546 gl_info->gl_ops.gl.p_glPushMatrix();
3547 gl_info->gl_ops.gl.p_glLoadIdentity();
3548 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3549 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3550 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3551 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3552 gl_info->gl_ops.gl.p_glPopMatrix();
3553 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3555 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3556 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3557 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3558 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3560 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3561 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3562 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3563 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3567 case WINED3DTSS_TCI_SPHEREMAP:
3568 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3569 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3570 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3572 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3573 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3574 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3575 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3580 FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3581 state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3582 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3583 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3584 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3585 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3586 checkGLcall("Disable texgen.");
3591 /* Update the texture matrix. */
3592 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3593 transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3595 if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3597 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3598 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3599 * and do all the things linked to it
3600 * TODO: Tidy that up to reload only the arrays of the changed unit
3602 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3604 unload_tex_coords(gl_info);
3605 load_tex_coords(context, &device->strided_streams, &curVBO, state);
3609 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3611 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3612 const struct wined3d_shader *ps = state->pixel_shader;
3614 /* The pixel shader has to know the luminance scale. Do a constants update. */
3615 if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3616 context->load_constants = 1;
3619 static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3621 const DWORD sampler = state_id - STATE_SAMPLER(0);
3622 const struct wined3d_texture *texture = state->textures[sampler];
3624 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3626 if(!texture) return;
3627 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3628 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3629 * scaling is reapplied or removed, the texture matrix has to be reapplied
3631 * The mapped stage is already active because the sampler() function below, which is part of the
3634 if (sampler < MAX_TEXTURES)
3636 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3638 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3640 const struct wined3d_device *device = context->swapchain->device;
3643 context->lastWasPow2Texture |= 1 << sampler;
3645 context->lastWasPow2Texture &= ~(1 << sampler);
3647 transform_texture(context, state,
3648 STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3653 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3655 const struct wined3d_device *device = context->swapchain->device;
3656 DWORD sampler = state_id - STATE_SAMPLER(0);
3657 DWORD mapped_stage = device->texUnitMap[sampler];
3658 const struct wined3d_gl_info *gl_info = context->gl_info;
3664 TRACE("Sampler: %d\n", sampler);
3665 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3666 * only has to bind textures and set the per texture states
3669 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3671 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3675 if (mapped_stage >= gl_info->limits.combined_samplers)
3679 context_active_texture(context, gl_info, mapped_stage);
3681 if (state->textures[sampler])
3683 struct wined3d_texture *texture = state->textures[sampler];
3684 BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3686 texture->texture_ops->texture_bind(texture, context, srgb);
3687 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3689 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3691 tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3692 gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3693 GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f);
3694 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3697 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3699 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3701 /* If color keying is enabled update the alpha test, it
3702 * depends on the existence of a color key in stage 0. */
3703 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3707 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3708 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3709 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3713 if (sampler < state->lowest_disabled_stage)
3715 /* TODO: What should I do with pixel shaders here ??? */
3716 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3718 /* If color keying is enabled update the alpha test, it
3719 * depends on the existence of a color key in stage 0. */
3720 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3722 } /* Otherwise tex_colorop disables the stage */
3723 context_bind_texture(context, GL_NONE, 0);
3727 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3733 if (!context->last_was_pshader)
3735 /* Former draw without a pixel shader, some samplers may be
3736 * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3737 * make sure to enable them. */
3738 for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3740 if (!isStateDirty(context, STATE_SAMPLER(i)))
3741 sampler(context, state, STATE_SAMPLER(i));
3743 context->last_was_pshader = TRUE;
3747 /* Otherwise all samplers were activated by the code above in
3748 * earlier draws, or by sampler() if a different texture was
3749 * bound. I don't have to do anything. */
3754 /* Disabled the pixel shader - color ops weren't applied while it was
3755 * enabled, so re-apply them. */
3756 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3758 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3759 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3761 context->last_was_pshader = FALSE;
3764 context->select_shader = 1;
3765 context->load_constants = 1;
3768 static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3770 context->select_shader = 1;
3773 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3775 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3776 const struct wined3d_shader *ps = state->pixel_shader;
3778 /* The pixel shader has to know the bump env matrix. Do a constants update. */
3779 if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3780 context->load_constants = 1;
3783 static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3785 const struct wined3d_gl_info *gl_info = context->gl_info;
3787 /* This function is called by transform_view below if the view matrix was changed too
3789 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3790 * does not always update the world matrix, only on a switch between transformed
3791 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3792 * draw, but that should be rather rare and cheaper in total.
3794 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3795 checkGLcall("glMatrixMode");
3797 if (context->last_was_rhw)
3799 gl_info->gl_ops.gl.p_glLoadIdentity();
3800 checkGLcall("glLoadIdentity()");
3804 /* In the general case, the view matrix is the identity matrix */
3805 if (context->swapchain->device->view_ident)
3807 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3808 checkGLcall("glLoadMatrixf");
3812 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3813 checkGLcall("glLoadMatrixf");
3814 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3815 checkGLcall("glMultMatrixf");
3820 static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3822 const struct wined3d_gl_info *gl_info = context->gl_info;
3823 UINT index = state_id - STATE_CLIPPLANE(0);
3826 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.clipplanes)
3829 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3830 gl_info->gl_ops.gl.p_glPushMatrix();
3832 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3834 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3836 /* With vertex shaders, clip planes are not transformed in Direct3D,
3837 * while in OpenGL they are still transformed by the model view matix. */
3838 gl_info->gl_ops.gl.p_glLoadIdentity();
3840 plane[0] = state->clip_planes[index].x;
3841 plane[1] = state->clip_planes[index].y;
3842 plane[2] = state->clip_planes[index].z;
3843 plane[3] = state->clip_planes[index].w;
3845 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3846 plane[0], plane[1], plane[2], plane[3]);
3847 gl_info->gl_ops.gl.p_glClipPlane(GL_CLIP_PLANE0 + index, plane);
3848 checkGLcall("glClipPlane");
3850 gl_info->gl_ops.gl.p_glPopMatrix();
3853 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3855 UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3856 const struct wined3d_gl_info *gl_info = context->gl_info;
3859 TRACE("Setting world matrix %d\n", matrix);
3861 if (matrix >= gl_info->limits.blends)
3863 WARN("Unsupported blend matrix set\n");
3867 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3870 /* GL_MODELVIEW0_ARB: 0x1700
3871 * GL_MODELVIEW1_ARB: 0x850a
3872 * GL_MODELVIEW2_ARB: 0x8722
3873 * GL_MODELVIEW3_ARB: 0x8723
3875 * GL_MODELVIEW31_ARB: 0x873f
3877 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3878 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3880 gl_info->gl_ops.gl.p_glMatrixMode(glMat);
3881 checkGLcall("glMatrixMode(glMat)");
3883 /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3884 * matrices while gl uses only 2. To avoid weighting the view matrix
3885 * incorrectly it has to be multiplied into every GL modelview matrix. */
3886 if (context->swapchain->device->view_ident)
3888 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3889 checkGLcall("glLoadMatrixf");
3893 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3894 checkGLcall("glLoadMatrixf");
3895 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3896 checkGLcall("glMultMatrixf");
3900 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3902 enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3903 static unsigned int once;
3905 if (f == WINED3D_VBF_DISABLE)
3908 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3909 else WARN("Vertex blend flags %#x not supported.\n", f);
3912 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3914 enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3915 struct wined3d_device *device = context->swapchain->device;
3916 const struct wined3d_gl_info *gl_info = context->gl_info;
3917 static unsigned int once;
3921 case WINED3D_VBF_1WEIGHTS:
3922 case WINED3D_VBF_2WEIGHTS:
3923 case WINED3D_VBF_3WEIGHTS:
3924 gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB);
3925 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3927 /* D3D adds one more matrix which has weight (1 - sum(weights)).
3928 * This is enabled at context creation with enabling
3929 * GL_WEIGHT_SUM_UNITY_ARB. */
3930 GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3932 if (!device->vertexBlendUsed)
3935 for (i = 1; i < gl_info->limits.blends; ++i)
3937 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3938 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3940 device->vertexBlendUsed = TRUE;
3944 case WINED3D_VBF_TWEENING:
3945 case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3946 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3947 else WARN("Vertex blend flags %#x not supported.\n", val);
3949 case WINED3D_VBF_DISABLE:
3950 gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB);
3951 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3956 static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3958 const struct wined3d_gl_info *gl_info = context->gl_info;
3959 const struct wined3d_light_info *light = NULL;
3962 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3963 * NOTE: We have to reset the positions even if the light/plane is not currently
3964 * enabled, since the call to enable it will not reset the position.
3965 * NOTE2: Apparently texture transforms do NOT need reapplying
3968 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3969 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3970 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3971 checkGLcall("glLoadMatrixf(...)");
3973 /* Reset lights. TODO: Call light apply func */
3974 for (k = 0; k < gl_info->limits.lights; ++k)
3976 if (!(light = state->lights[k]))
3978 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3979 checkGLcall("glLightfv posn");
3980 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3981 checkGLcall("glLightfv dirn");
3984 /* Reset Clipping Planes */
3985 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3987 if (!isStateDirty(context, STATE_CLIPPLANE(k)))
3988 clipplane(context, state, STATE_CLIPPLANE(k));
3991 if (context->last_was_rhw)
3993 gl_info->gl_ops.gl.p_glLoadIdentity();
3994 checkGLcall("glLoadIdentity()");
3995 /* No need to update the world matrix, the identity is fine */
3999 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
4000 * No need to do it here if the state is scheduled for update. */
4001 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4002 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4004 /* Avoid looping over a number of matrices if the app never used the functionality */
4005 if (context->swapchain->device->vertexBlendUsed)
4007 for (k = 1; k < gl_info->limits.blends; ++k)
4009 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
4010 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
4015 static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4017 const struct wined3d_gl_info *gl_info = context->gl_info;
4019 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
4020 checkGLcall("glMatrixMode(GL_PROJECTION)");
4022 /* There are a couple of additional things we have to take into account
4023 * here besides the projection transformation itself:
4024 * - We need to flip along the y-axis in case of offscreen rendering.
4025 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
4026 * - D3D coordinates refer to pixel centers while GL coordinates refer
4028 * - D3D has a top-left filling convention. We need to maintain this
4029 * even after the y-flip mentioned above.
4030 * In order to handle the last two points, we translate by
4031 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
4032 * translating slightly less than half a pixel. We want the difference to
4033 * be large enough that it doesn't get lost due to rounding inside the
4034 * driver, but small enough to prevent it from interfering with any
4037 if (context->last_was_rhw)
4039 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
4040 double x = state->viewport.x;
4041 double y = state->viewport.y;
4042 double w = state->viewport.width;
4043 double h = state->viewport.height;
4044 double x_scale = 2.0 / w;
4045 double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
4046 double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
4047 double y_offset = context->render_offscreen
4048 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
4049 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
4050 const GLdouble projection[] =
4052 x_scale, 0.0, 0.0, 0.0,
4053 0.0, y_scale, 0.0, 0.0,
4055 x_offset, y_offset, -1.0, 1.0,
4058 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4059 checkGLcall("glLoadMatrixd");
4063 double y_scale = context->render_offscreen ? -1.0 : 1.0;
4064 double x_offset = (63.0 / 64.0) / state->viewport.width;
4065 double y_offset = context->render_offscreen
4066 ? (63.0 / 64.0) / state->viewport.height
4067 : -(63.0 / 64.0) / state->viewport.height;
4068 const GLdouble projection[] =
4071 0.0, y_scale, 0.0, 0.0,
4073 x_offset, y_offset, -1.0, 1.0,
4076 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4077 checkGLcall("glLoadMatrixd");
4079 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4080 checkGLcall("glLoadMatrixf");
4084 /* This should match any arrays loaded in load_vertex_data.
4085 * TODO: Only load / unload arrays if we have to. */
4086 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4088 gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
4089 gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
4090 gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
4091 if (gl_info->supported[EXT_SECONDARY_COLOR])
4092 gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4093 if (gl_info->supported[ARB_VERTEX_BLEND])
4094 gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4095 unload_tex_coords(gl_info);
4098 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4100 const struct wined3d_gl_info *gl_info = context->gl_info;
4102 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4103 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4104 if (gl_info->supported[ARB_INSTANCED_ARRAYS])
4105 GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
4107 context->numbered_array_mask &= ~(1 << i);
4110 /* This should match any arrays loaded in loadNumberedArrays
4111 * TODO: Only load / unload arrays if we have to. */
4112 static void unload_numbered_arrays(struct wined3d_context *context)
4114 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4117 for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4118 unload_numbered_array(context, i);
4122 static void load_numbered_arrays(struct wined3d_context *context,
4123 const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4125 struct wined3d_device *device = context->swapchain->device;
4126 const struct wined3d_gl_info *gl_info = context->gl_info;
4127 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4130 /* Default to no instancing */
4131 device->instance_count = 0;
4133 for (i = 0; i < MAX_ATTRIBS; i++)
4135 const struct wined3d_stream_state *stream;
4137 if (!(stream_info->use_map & (1 << i)))
4139 if (context->numbered_array_mask & (1 << i))
4140 unload_numbered_array(context, i);
4141 if (state->vertex_shader->reg_maps.input_registers & (1 << i))
4142 GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
4146 stream = &state->streams[stream_info->elements[i].stream_idx];
4148 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4150 if (!device->instance_count)
4151 device->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
4153 if (!gl_info->supported[ARB_INSTANCED_ARRAYS])
4155 /* Unload instanced arrays, they will be loaded using
4156 * immediate mode instead. */
4157 if (context->numbered_array_mask & (1 << i))
4158 unload_numbered_array(context, i);
4162 GL_EXTCALL(glVertexAttribDivisorARB(i, 1));
4164 else if (gl_info->supported[ARB_INSTANCED_ARRAYS])
4166 GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
4169 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4171 if (stream_info->elements[i].stride)
4173 if (curVBO != stream_info->elements[i].data.buffer_object)
4175 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4176 checkGLcall("glBindBufferARB");
4177 curVBO = stream_info->elements[i].data.buffer_object;
4179 /* Use the VBO to find out if a vertex buffer exists, not the vb
4180 * pointer. vb can point to a user pointer data blob. In that case
4181 * curVBO will be 0. If there is a vertex buffer but no vbo we
4182 * won't be load converted attributes anyway. */
4183 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4184 stream_info->elements[i].format->gl_vtx_type,
4185 stream_info->elements[i].format->gl_normalized,
4186 stream_info->elements[i].stride, stream_info->elements[i].data.addr
4187 + state->load_base_vertex_index * stream_info->elements[i].stride));
4189 if (!(context->numbered_array_mask & (1 << i)))
4191 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4192 context->numbered_array_mask |= (1 << i);
4197 /* Stride = 0 means always the same values.
4198 * glVertexAttribPointerARB doesn't do that. Instead disable the
4199 * pointer and set up the attribute statically. But we have to
4200 * figure out the system memory address. */
4201 const BYTE *ptr = stream_info->elements[i].data.addr;
4202 if (stream_info->elements[i].data.buffer_object)
4204 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4207 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4209 switch (stream_info->elements[i].format->id)
4211 case WINED3DFMT_R32_FLOAT:
4212 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4214 case WINED3DFMT_R32G32_FLOAT:
4215 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4217 case WINED3DFMT_R32G32B32_FLOAT:
4218 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4220 case WINED3DFMT_R32G32B32A32_FLOAT:
4221 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4224 case WINED3DFMT_R8G8B8A8_UINT:
4225 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4227 case WINED3DFMT_B8G8R8A8_UNORM:
4228 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4230 const DWORD *src = (const DWORD *)ptr;
4231 DWORD c = *src & 0xff00ff00;
4232 c |= (*src & 0xff0000) >> 16;
4233 c |= (*src & 0xff) << 16;
4234 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4237 /* else fallthrough */
4238 case WINED3DFMT_R8G8B8A8_UNORM:
4239 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4242 case WINED3DFMT_R16G16_SINT:
4243 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4245 case WINED3DFMT_R16G16B16A16_SINT:
4246 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4249 case WINED3DFMT_R16G16_SNORM:
4251 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4252 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4255 case WINED3DFMT_R16G16_UNORM:
4257 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4258 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4261 case WINED3DFMT_R16G16B16A16_SNORM:
4262 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4264 case WINED3DFMT_R16G16B16A16_UNORM:
4265 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4268 case WINED3DFMT_R10G10B10A2_UINT:
4269 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4270 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4272 case WINED3DFMT_R10G10B10A2_SNORM:
4273 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4274 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4277 case WINED3DFMT_R16G16_FLOAT:
4278 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4279 * byte float according to the IEEE standard
4281 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4283 case WINED3DFMT_R16G16B16A16_FLOAT:
4284 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4288 ERR("Unexpected declaration in stride 0 attributes\n");
4294 checkGLcall("Loading numbered arrays");
4297 static void load_vertex_data(const struct wined3d_context *context,
4298 const struct wined3d_stream_info *si, const struct wined3d_state *state)
4300 struct wined3d_device *device = context->swapchain->device;
4301 const struct wined3d_gl_info *gl_info = context->gl_info;
4302 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4303 const struct wined3d_stream_info_element *e;
4305 TRACE("Using fast vertex array code\n");
4307 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4308 device->instance_count = 0;
4310 /* Blend Data ---------------------------------------------- */
4311 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4312 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4314 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4316 if (gl_info->supported[ARB_VERTEX_BLEND])
4318 TRACE("Blend %u %p %u\n", e->format->component_count,
4319 e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4321 gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4322 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4324 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4326 if (curVBO != e->data.buffer_object)
4328 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4329 checkGLcall("glBindBufferARB");
4330 curVBO = e->data.buffer_object;
4333 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4334 e->format->gl_vtx_format,
4335 e->format->gl_vtx_type,
4337 e->data.addr + state->load_base_vertex_index * e->stride);
4338 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4339 e->data.addr + state->load_base_vertex_index * e->stride));
4341 checkGLcall("glWeightPointerARB");
4343 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4348 FIXME("blendMatrixIndices support\n");
4353 /* TODO: support blends in drawStridedSlow
4354 * No need to write a FIXME here, this is done after the general vertex decl decoding
4356 WARN("unsupported blending in openGl\n");
4361 if (gl_info->supported[ARB_VERTEX_BLEND])
4363 static const GLbyte one = 1;
4364 GL_EXTCALL(glWeightbvARB(1, &one));
4365 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4369 /* Point Size ----------------------------------------------*/
4370 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4372 /* no such functionality in the fixed function GL pipeline */
4373 TRACE("Cannot change ptSize here in openGl\n");
4374 /* TODO: Implement this function in using shaders if they are available */
4377 /* Vertex Pointers -----------------------------------------*/
4378 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4380 e = &si->elements[WINED3D_FFP_POSITION];
4382 if (curVBO != e->data.buffer_object)
4384 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4385 checkGLcall("glBindBufferARB");
4386 curVBO = e->data.buffer_object;
4389 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4390 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4391 e->data.addr + state->load_base_vertex_index * e->stride);
4392 gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4393 e->data.addr + state->load_base_vertex_index * e->stride);
4394 checkGLcall("glVertexPointer(...)");
4395 gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
4396 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4399 /* Normals -------------------------------------------------*/
4400 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4402 e = &si->elements[WINED3D_FFP_NORMAL];
4404 if (curVBO != e->data.buffer_object)
4406 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4407 checkGLcall("glBindBufferARB");
4408 curVBO = e->data.buffer_object;
4411 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4412 e->data.addr + state->load_base_vertex_index * e->stride);
4413 gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
4414 e->data.addr + state->load_base_vertex_index * e->stride);
4415 checkGLcall("glNormalPointer(...)");
4416 gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
4417 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4422 gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
4423 checkGLcall("glNormal3f(0, 0, 0)");
4426 /* Diffuse Colour --------------------------------------------*/
4427 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4429 e = &si->elements[WINED3D_FFP_DIFFUSE];
4431 if (curVBO != e->data.buffer_object)
4433 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4434 checkGLcall("glBindBufferARB");
4435 curVBO = e->data.buffer_object;
4438 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4439 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4440 e->data.addr + state->load_base_vertex_index * e->stride);
4441 gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4442 e->data.addr + state->load_base_vertex_index * e->stride);
4443 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4444 gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
4445 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4450 gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4451 checkGLcall("glColor4f(1, 1, 1, 1)");
4454 /* Specular Colour ------------------------------------------*/
4455 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4457 TRACE("setting specular colour\n");
4459 e = &si->elements[WINED3D_FFP_SPECULAR];
4461 if (gl_info->supported[EXT_SECONDARY_COLOR])
4463 GLenum type = e->format->gl_vtx_type;
4464 GLint format = e->format->gl_vtx_format;
4466 if (curVBO != e->data.buffer_object)
4468 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4469 checkGLcall("glBindBufferARB");
4470 curVBO = e->data.buffer_object;
4473 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4475 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4476 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4477 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4478 * 4 component secondary colors use it
4480 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4481 e->data.addr + state->load_base_vertex_index * e->stride);
4482 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4483 e->data.addr + state->load_base_vertex_index * e->stride));
4484 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4490 case GL_UNSIGNED_BYTE:
4491 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4492 e->data.addr + state->load_base_vertex_index * e->stride);
4493 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4494 e->data.addr + state->load_base_vertex_index * e->stride));
4495 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4499 FIXME("Add 4 component specular color pointers for type %x\n", type);
4500 /* Make sure that the right color component is dropped */
4501 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4502 e->data.addr + state->load_base_vertex_index * e->stride);
4503 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4504 e->data.addr + state->load_base_vertex_index * e->stride));
4505 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4508 gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4509 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4513 WARN("Specular colour is not supported in this GL implementation.\n");
4518 if (gl_info->supported[EXT_SECONDARY_COLOR])
4520 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4521 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4525 WARN("Specular colour is not supported in this GL implementation.\n");
4529 /* Texture coords -------------------------------------------*/
4530 load_tex_coords(context, si, &curVBO, state);
4533 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4535 const struct wined3d_device *device = context->swapchain->device;
4536 BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4537 BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4539 if (isStateDirty(context, STATE_VDECL)) return;
4540 if (context->numberedArraysLoaded && !load_numbered)
4542 unload_numbered_arrays(context);
4543 context->numberedArraysLoaded = FALSE;
4544 context->numbered_array_mask = 0;
4546 else if (context->namedArraysLoaded)
4548 unload_vertex_data(context->gl_info);
4549 context->namedArraysLoaded = FALSE;
4554 TRACE("Loading numbered arrays\n");
4555 load_numbered_arrays(context, &device->strided_streams, state);
4556 context->numberedArraysLoaded = TRUE;
4558 else if (load_named)
4560 TRACE("Loading vertex data\n");
4561 load_vertex_data(context, &device->strided_streams, state);
4562 context->namedArraysLoaded = TRUE;
4566 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4568 if (isStateDirty(context, STATE_STREAMSRC))
4570 streamsrc(context, state, STATE_STREAMSRC);
4573 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4575 const struct wined3d_device *device = context->swapchain->device;
4576 const struct wined3d_gl_info *gl_info = context->gl_info;
4577 BOOL useVertexShaderFunction = use_vs(state);
4578 BOOL updateFog = FALSE;
4580 BOOL wasrhw = context->last_was_rhw;
4583 transformed = device->strided_streams.position_transformed;
4584 if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4587 context->last_was_rhw = transformed;
4589 /* Don't have to apply the matrices when vertex shaders are used. When
4590 * vshaders are turned off this function will be called again anyway to
4591 * make sure they're properly set. */
4592 if (!useVertexShaderFunction)
4594 /* TODO: Move this mainly to the viewport state and only apply when
4595 * the vp has changed or transformed / untransformed was switched. */
4596 if (wasrhw != context->last_was_rhw
4597 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4598 && !isStateDirty(context, STATE_VIEWPORT))
4599 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4600 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4603 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4604 * this check will fail and the matrix not applied again. This is OK because a simple
4605 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4606 * needs of the vertex declaration.
4608 * World and view matrix go into the same gl matrix, so only apply them when neither is
4611 if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4612 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4613 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4614 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4615 state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4616 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4617 state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4619 if (context->last_was_vshader)
4623 if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4624 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4626 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4628 clipplane(context, state, STATE_CLIPPLANE(i));
4631 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4632 state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4636 if(!context->last_was_vshader) {
4637 static BOOL warned = FALSE;
4638 if(!device->vs_clipping) {
4639 /* Disable all clip planes to get defined results on all drivers. See comment in the
4640 * state_clipping state handler
4642 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4644 gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i);
4645 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4648 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4650 FIXME("Clipping not supported with vertex shaders\n");
4656 /* Apply the transform matrices when switching from rhw
4657 * drawing to vertex shaders. Vertex shaders themselves do
4658 * not need it, but the matrices are not reapplied
4659 * automatically when switching back from vertex shaders to
4660 * fixed function processing. So make sure we leave the fixed
4661 * function vertex processing states back in a sane state
4662 * before switching to shaders. */
4663 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4664 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4665 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4666 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4670 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4671 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4672 * device->vs_clipping is false.
4674 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4676 clipplane(context, state, STATE_CLIPPLANE(i));
4681 context->last_was_vshader = useVertexShaderFunction;
4682 context->select_shader = 1;
4683 context->load_constants = 1;
4686 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4688 if (!useVertexShaderFunction)
4692 for (i = 0; i < MAX_TEXTURES; ++i)
4694 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4695 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4699 if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4700 state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4703 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4705 const struct wined3d_surface *target = state->fb->render_targets[0];
4706 const struct wined3d_gl_info *gl_info = context->gl_info;
4707 struct wined3d_viewport vp = state->viewport;
4709 if (vp.width > target->resource.width)
4710 vp.width = target->resource.width;
4711 if (vp.height > target->resource.height)
4712 vp.height = target->resource.height;
4714 gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
4715 checkGLcall("glDepthRange");
4716 /* Note: GL requires lower left, DirectX supplies upper left. This is
4717 * reversed when using offscreen rendering. */
4718 if (context->render_offscreen)
4720 gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
4726 target->get_drawable_size(context, &width, &height);
4727 gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)),
4728 vp.width, vp.height);
4731 checkGLcall("glViewport");
4734 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4736 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4737 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4738 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4739 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4740 /* Update the position fixup. */
4741 context->load_constants = 1;
4744 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4746 const struct wined3d_gl_info *gl_info = context->gl_info;
4747 UINT Index = state_id - STATE_ACTIVELIGHT(0);
4748 const struct wined3d_light_info *lightInfo = state->lights[Index];
4752 gl_info->gl_ops.gl.p_glDisable(GL_LIGHT0 + Index);
4753 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4758 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4760 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4761 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
4762 gl_info->gl_ops.gl.p_glPushMatrix();
4763 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4766 colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4767 colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4768 colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4769 colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4770 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4771 checkGLcall("glLightfv");
4774 colRGBA[0] = lightInfo->OriginalParms.specular.r;
4775 colRGBA[1] = lightInfo->OriginalParms.specular.g;
4776 colRGBA[2] = lightInfo->OriginalParms.specular.b;
4777 colRGBA[3] = lightInfo->OriginalParms.specular.a;
4778 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4779 checkGLcall("glLightfv");
4782 colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4783 colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4784 colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4785 colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4786 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4787 checkGLcall("glLightfv");
4789 if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4790 quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4792 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4794 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4795 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4796 * Attenuation0 to NaN and crashes in the gl lib
4799 switch (lightInfo->OriginalParms.type)
4801 case WINED3D_LIGHT_POINT:
4803 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4804 checkGLcall("glLightfv");
4805 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4806 checkGLcall("glLightf");
4807 /* Attenuation - Are these right? guessing... */
4808 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4809 lightInfo->OriginalParms.attenuation0);
4810 checkGLcall("glLightf");
4811 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4812 lightInfo->OriginalParms.attenuation1);
4813 checkGLcall("glLightf");
4814 if (quad_att < lightInfo->OriginalParms.attenuation2)
4815 quad_att = lightInfo->OriginalParms.attenuation2;
4816 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4817 checkGLcall("glLightf");
4821 case WINED3D_LIGHT_SPOT:
4823 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4824 checkGLcall("glLightfv");
4826 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4827 checkGLcall("glLightfv");
4828 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4829 checkGLcall("glLightf");
4830 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4831 checkGLcall("glLightf");
4832 /* Attenuation - Are these right? guessing... */
4833 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4834 lightInfo->OriginalParms.attenuation0);
4835 checkGLcall("glLightf");
4836 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4837 lightInfo->OriginalParms.attenuation1);
4838 checkGLcall("glLightf");
4839 if (quad_att < lightInfo->OriginalParms.attenuation2)
4840 quad_att = lightInfo->OriginalParms.attenuation2;
4841 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4842 checkGLcall("glLightf");
4846 case WINED3D_LIGHT_DIRECTIONAL:
4848 /* Note GL uses w position of 0 for direction! */
4849 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4850 checkGLcall("glLightfv");
4851 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4852 checkGLcall("glLightf");
4853 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4854 checkGLcall("glLightf");
4858 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4861 /* Restore the modelview matrix */
4862 gl_info->gl_ops.gl.p_glPopMatrix();
4864 gl_info->gl_ops.gl.p_glEnable(GL_LIGHT0 + Index);
4865 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4869 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4871 const struct wined3d_gl_info *gl_info = context->gl_info;
4872 const RECT *r = &state->scissor_rect;
4874 /* Warning: glScissor uses window coordinates, not viewport coordinates,
4875 * so our viewport correction does not apply. Warning2: Even in windowed
4876 * mode the coords are relative to the window, not the screen. */
4877 TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4879 if (context->render_offscreen)
4881 gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4885 const struct wined3d_surface *target = state->fb->render_targets[0];
4889 target->get_drawable_size(context, &width, &height);
4890 gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4892 checkGLcall("glScissor");
4895 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4897 const struct wined3d_stream_info *stream_info = &context->swapchain->device->strided_streams;
4898 const struct wined3d_gl_info *gl_info = context->gl_info;
4900 if (!state->index_buffer || !stream_info->all_vbo)
4902 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4906 struct wined3d_buffer *ib = state->index_buffer;
4907 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4911 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4913 const struct wined3d_gl_info *gl_info = context->gl_info;
4915 if (context->render_offscreen)
4917 gl_info->gl_ops.gl.p_glFrontFace(GL_CCW);
4918 checkGLcall("glFrontFace(GL_CCW)");
4922 gl_info->gl_ops.gl.p_glFrontFace(GL_CW);
4923 checkGLcall("glFrontFace(GL_CW)");
4927 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4933 WARN("Point sprite coordinate origin switching not supported.\n");
4938 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4940 const struct wined3d_gl_info *gl_info = context->gl_info;
4941 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4943 if (gl_info->supported[NV_POINT_SPRITE])
4945 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4946 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4950 void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4952 const struct wined3d_gl_info *gl_info = context->gl_info;
4953 const struct wined3d_surface *rt = state->fb->render_targets[0];
4955 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
4957 if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
4958 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
4959 gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
4961 gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
4964 const struct StateEntryTemplate misc_state_template[] = {
4965 { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4966 { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4967 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4968 { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4969 { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4970 { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4971 { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4972 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4973 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4974 { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4975 { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
4976 { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
4977 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4978 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4979 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4980 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4982 /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4983 * vshader loadings are untied from each other
4985 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4986 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4987 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4988 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4989 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4990 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4991 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4992 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4993 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4994 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4995 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4996 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4997 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4998 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4999 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5000 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5001 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5003 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5004 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5005 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5006 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5007 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5008 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5009 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5010 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5011 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5012 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5013 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5014 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5015 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5016 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5017 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5018 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5019 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5020 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5021 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5022 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5023 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5024 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5025 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5026 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5027 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5028 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5029 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5030 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5031 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5032 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5033 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5034 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5036 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
5037 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
5038 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
5039 { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
5040 { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
5042 { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
5044 { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
5045 { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
5046 { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
5047 { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
5048 { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
5050 { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
5051 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
5052 { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5053 { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5054 { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5055 { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
5056 { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
5057 { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
5058 { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
5059 { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
5060 { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
5061 { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
5062 { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
5063 { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
5064 { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
5065 { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
5066 { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
5067 { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
5068 { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5069 { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5070 { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5071 { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5072 { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5073 { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5074 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
5075 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
5076 { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5077 { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5078 { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5079 { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5080 { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5081 { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5082 { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5083 { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5084 { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5085 { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5086 { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5087 { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5088 { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5089 { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5090 { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5091 { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5092 { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5093 { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5094 { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5095 { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5096 { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5097 { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5098 { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5099 { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5100 { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5101 { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5102 { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5103 { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5104 { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5105 { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5106 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5107 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5108 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5109 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5110 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5111 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
5112 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5113 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5114 { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5115 { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5116 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5117 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5118 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5119 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5120 { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5121 { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5122 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5123 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5124 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5125 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5126 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5127 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5128 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5129 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5130 { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5131 { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5133 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5134 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5135 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5136 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5137 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5138 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5139 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5140 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5141 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5142 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5143 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5144 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5145 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5146 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5147 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5148 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5149 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5150 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5151 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5152 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5153 { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
5154 { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
5155 { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
5156 { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
5157 { STATE_GEOMETRY_SHADER, { STATE_GEOMETRY_SHADER, state_geometry_shader}, WINED3D_GL_EXT_NONE },
5158 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5161 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5162 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5163 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5164 { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5165 { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5167 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5168 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5169 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5170 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5171 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5172 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5173 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5174 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5175 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5176 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5177 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5178 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5179 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5180 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5181 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5182 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5183 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5184 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5185 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5186 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5187 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5188 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5189 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5190 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5191 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5192 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5193 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5194 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5195 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5196 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5197 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5198 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5200 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5201 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5202 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5203 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5204 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5205 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5206 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5207 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5209 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5210 /* Transform states follow */
5211 { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5396 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5397 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5400 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5401 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5402 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5403 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5405 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5406 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5407 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5411 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5412 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5413 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5414 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5415 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5416 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5417 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5418 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5419 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5420 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5421 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5422 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5423 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5424 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5425 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5426 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5427 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5428 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5429 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5430 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5431 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5432 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5433 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5434 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5435 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5436 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5437 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5438 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5439 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5440 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5441 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5442 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5443 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5444 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5445 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5446 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5447 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5448 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5449 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5450 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5451 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5452 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5453 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5454 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5455 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5456 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5457 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5458 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5459 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5460 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5461 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5462 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5463 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5464 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5465 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5466 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5467 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5468 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5469 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5470 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5471 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5472 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5473 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5474 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5475 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5476 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5477 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5478 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5479 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5480 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5481 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5482 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5483 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5484 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5485 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5486 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5487 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5488 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5489 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5490 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5491 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5492 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5494 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5495 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5496 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5497 { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5498 { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5499 { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5500 { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5501 { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5502 { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5503 { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5504 { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5505 { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5506 { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5507 { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5508 { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5509 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5510 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5511 { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5512 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5513 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5514 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5515 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5516 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5517 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5518 { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5519 { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5520 { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5521 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5522 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5523 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5524 { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5525 { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5527 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5528 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5529 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5531 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5532 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5533 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5534 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5535 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5536 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5537 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5538 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5539 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5540 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5541 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5542 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5543 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5544 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5545 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5546 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5547 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5548 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5549 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5550 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5551 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5552 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5553 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5554 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5555 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5558 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5559 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5560 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5561 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5562 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5563 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5564 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5565 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5566 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5567 { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5568 { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5569 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5570 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5571 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5572 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5573 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5574 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5575 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5576 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5577 { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5578 { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5579 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5580 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5581 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5582 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5583 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5584 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5585 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5586 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5587 { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5588 { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5589 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5590 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5591 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5592 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5593 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5594 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5595 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5596 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5597 { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5598 { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5599 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5600 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5601 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5602 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5603 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5604 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5605 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5606 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5607 { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5608 { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5609 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5610 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5611 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5612 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5613 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5614 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5615 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5616 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5617 { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5618 { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5619 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5620 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5621 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5622 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5623 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5624 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5625 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5626 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5627 { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5628 { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5629 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5630 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5631 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5632 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5633 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5634 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5635 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5636 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5637 { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5638 { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5639 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5640 { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5641 { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5642 { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5643 { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5644 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5645 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5646 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5647 { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5648 { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5649 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5650 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5651 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5652 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5653 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5654 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5655 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5656 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5657 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5660 /* Context activation is done by the caller. */
5661 static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5663 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5665 caps->wined3d_caps = 0;
5666 caps->PrimitiveMiscCaps = 0;
5667 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5668 | WINED3DTEXOPCAPS_ADDSIGNED
5669 | WINED3DTEXOPCAPS_ADDSIGNED2X
5670 | WINED3DTEXOPCAPS_MODULATE
5671 | WINED3DTEXOPCAPS_MODULATE2X
5672 | WINED3DTEXOPCAPS_MODULATE4X
5673 | WINED3DTEXOPCAPS_SELECTARG1
5674 | WINED3DTEXOPCAPS_SELECTARG2
5675 | WINED3DTEXOPCAPS_DISABLE;
5677 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5678 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5679 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5681 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5682 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5683 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5684 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5685 | WINED3DTEXOPCAPS_LERP
5686 | WINED3DTEXOPCAPS_SUBTRACT;
5688 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5689 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5691 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5692 | WINED3DTEXOPCAPS_MULTIPLYADD
5693 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5694 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5695 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5697 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5698 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5700 caps->MaxTextureBlendStages = gl_info->limits.textures;
5701 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5704 static void *ffp_fragment_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
5709 static void ffp_fragment_free(struct wined3d_device *device) {}
5710 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5714 TRACE("Checking support for fixup:\n");
5715 dump_color_fixup_desc(fixup);
5718 /* We only support identity conversions. */
5719 if (is_identity_fixup(fixup))
5725 TRACE("[FAILED]\n");
5729 const struct fragment_pipeline ffp_fragment_pipeline = {
5731 ffp_fragment_get_caps,
5734 ffp_color_fixup_supported,
5735 ffp_fragmentstate_template,
5738 static void fp_none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5740 static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5742 memset(caps, 0, sizeof(*caps));
5745 static void *fp_none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
5750 static void fp_none_free(struct wined3d_device *device) {}
5752 static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
5754 return is_identity_fixup(fixup);
5757 const struct fragment_pipeline none_fragment_pipe =
5763 fp_none_color_fixup_supported,
5767 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5770 for(i = 0; funcs[i]; i++);
5774 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5776 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5777 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5780 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5782 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5783 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5784 context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5787 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5789 unsigned int start, last, i;
5791 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5792 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5793 for (i = start; i <= last; ++i)
5795 state_table[i].representative = 0;
5796 state_table[i].apply = state_undefined;
5799 start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
5800 last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5801 for (i = start; i <= last; ++i)
5803 state_table[i].representative = 0;
5804 state_table[i].apply = state_undefined;
5807 start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5808 last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5809 for (i = start; i <= last; ++i)
5811 state_table[i].representative = 0;
5812 state_table[i].apply = state_undefined;
5816 static void validate_state_table(struct StateEntry *state_table)
5838 static const DWORD simple_states[] =
5844 STATE_VERTEXSHADERCONSTANT,
5845 STATE_PIXELSHADERCONSTANT,
5847 STATE_GEOMETRY_SHADER,
5852 STATE_POINTSPRITECOORDORIGIN,
5853 STATE_BASEVERTEXINDEX,
5856 unsigned int i, current;
5858 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5860 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5862 if (!state_table[i].representative)
5863 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5865 else if (state_table[i].representative)
5866 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5868 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5871 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5873 if (!state_table[simple_states[i]].representative)
5874 ERR("State %s (%#x) should have a representative.\n",
5875 debug_d3dstate(simple_states[i]), simple_states[i]);
5878 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5880 DWORD rep = state_table[i].representative;
5883 if (state_table[rep].representative != rep)
5885 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5886 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5887 state_table[i].representative = 0;
5892 if (state_table[i].apply)
5893 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5895 else if (!state_table[i].apply)
5897 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5903 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5904 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5905 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5907 unsigned int i, type, handlers;
5908 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5909 const struct StateEntryTemplate *cur;
5910 BOOL set[STATE_HIGHEST + 1];
5912 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5914 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5915 StateTable[i].representative = 0;
5916 StateTable[i].apply = state_undefined;
5919 for(type = 0; type < 3; type++) {
5920 /* This switch decides the order in which the states are applied */
5922 case 0: cur = misc; break;
5923 case 1: cur = fragment->states; break;
5924 case 2: cur = vertex; break;
5925 default: cur = NULL; /* Stupid compiler */
5929 /* GL extension filtering should not prevent multiple handlers being applied from different
5932 memset(set, 0, sizeof(set));
5934 for(i = 0; cur[i].state; i++) {
5935 APPLYSTATEFUNC *funcs_array;
5937 /* Only use the first matching state with the available extension from one template.
5939 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5940 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5942 * if GL_XYZ_fancy is supported, ignore the 2nd line
5944 if(set[cur[i].state]) continue;
5945 /* Skip state lines depending on unsupported extensions */
5946 if (!gl_info->supported[cur[i].extension]) continue;
5947 set[cur[i].state] = TRUE;
5948 /* In some cases having an extension means that nothing has to be
5949 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5950 * supported, the texture coordinate fixup can be ignored. If the
5951 * apply function is used, mark the state set(done above) to prevent
5952 * applying later lines, but do not record anything in the state
5955 if (!cur[i].content.representative) continue;
5957 handlers = num_handlers(multistate_funcs[cur[i].state]);
5958 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5961 StateTable[cur[i].state].apply = cur[i].content.apply;
5964 StateTable[cur[i].state].apply = multistate_apply_2;
5965 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5967 sizeof(**dev_multistate_funcs) * 2);
5968 if (!dev_multistate_funcs[cur[i].state]) {
5972 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5973 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5976 StateTable[cur[i].state].apply = multistate_apply_3;
5977 funcs_array = HeapReAlloc(GetProcessHeap(),
5979 dev_multistate_funcs[cur[i].state],
5980 sizeof(**dev_multistate_funcs) * 3);
5985 dev_multistate_funcs[cur[i].state] = funcs_array;
5986 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5989 ERR("Unexpected amount of state handlers for state %u: %u\n",
5990 cur[i].state, handlers + 1);
5993 if(StateTable[cur[i].state].representative &&
5994 StateTable[cur[i].state].representative != cur[i].content.representative) {
5995 FIXME("State %u has different representatives in different pipeline parts\n",
5998 StateTable[cur[i].state].representative = cur[i].content.representative;
6002 prune_invalid_states(StateTable, gl_info);
6003 validate_state_table(StateTable);
6008 for (i = 0; i <= STATE_HIGHEST; ++i) {
6009 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
6012 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
6014 return E_OUTOFMEMORY;