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
33 #include "wined3d_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
36 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
38 /* GL locking for state handlers is done by the caller. */
40 static void state_blendop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context);
42 static void state_undefined(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
44 ERR("Undefined state.\n");
47 static void state_nop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
49 TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state));
52 static void state_fillmode(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
54 WINED3DFILLMODE Value = stateblock->state.render_states[WINED3DRS_FILLMODE];
57 case WINED3DFILL_POINT:
58 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
59 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
61 case WINED3DFILL_WIREFRAME:
62 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
63 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
65 case WINED3DFILL_SOLID:
66 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
67 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
70 FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
74 static void state_lighting(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
76 /* Lighting is not enabled if transformed vertices are drawn
77 * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
78 * This state reads the decoded vertex declaration, so if it is dirty don't do anything. The
79 * vertex declaration applying function calls this function for updating
82 if(isStateDirty(context, STATE_VDECL)) {
86 if (stateblock->state.render_states[WINED3DRS_LIGHTING]
87 && !stateblock->device->strided_streams.position_transformed)
89 glEnable(GL_LIGHTING);
90 checkGLcall("glEnable GL_LIGHTING");
92 glDisable(GL_LIGHTING);
93 checkGLcall("glDisable GL_LIGHTING");
97 static void state_zenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
99 /* No z test without depth stencil buffers */
100 if (!stateblock->device->depth_stencil)
102 TRACE("No Z buffer - disabling depth test\n");
103 glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */
104 checkGLcall("glDisable GL_DEPTH_TEST");
108 switch (stateblock->state.render_states[WINED3DRS_ZENABLE])
110 case WINED3DZB_FALSE:
111 glDisable(GL_DEPTH_TEST);
112 checkGLcall("glDisable GL_DEPTH_TEST");
115 glEnable(GL_DEPTH_TEST);
116 checkGLcall("glEnable GL_DEPTH_TEST");
119 glEnable(GL_DEPTH_TEST);
120 checkGLcall("glEnable GL_DEPTH_TEST");
121 FIXME("W buffer is not well handled\n");
124 FIXME("Unrecognized D3DZBUFFERTYPE value %#x.\n",
125 stateblock->state.render_states[WINED3DRS_ZENABLE]);
129 static void state_cullmode(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
131 /* glFrontFace() is set in context.c at context init and on an
132 * offscreen / onscreen rendering switch. */
133 switch (stateblock->state.render_states[WINED3DRS_CULLMODE])
135 case WINED3DCULL_NONE:
136 glDisable(GL_CULL_FACE);
137 checkGLcall("glDisable GL_CULL_FACE");
140 glEnable(GL_CULL_FACE);
141 checkGLcall("glEnable GL_CULL_FACE");
142 glCullFace(GL_FRONT);
143 checkGLcall("glCullFace(GL_FRONT)");
145 case WINED3DCULL_CCW:
146 glEnable(GL_CULL_FACE);
147 checkGLcall("glEnable GL_CULL_FACE");
149 checkGLcall("glCullFace(GL_BACK)");
152 FIXME("Unrecognized/Unhandled WINED3DCULL value %#x.\n",
153 stateblock->state.render_states[WINED3DRS_CULLMODE]);
157 static void state_shademode(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
159 switch (stateblock->state.render_states[WINED3DRS_SHADEMODE])
161 case WINED3DSHADE_FLAT:
162 glShadeModel(GL_FLAT);
163 checkGLcall("glShadeModel(GL_FLAT)");
165 case WINED3DSHADE_GOURAUD:
166 glShadeModel(GL_SMOOTH);
167 checkGLcall("glShadeModel(GL_SMOOTH)");
169 case WINED3DSHADE_PHONG:
170 FIXME("WINED3DSHADE_PHONG isn't supported\n");
173 FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %#x.\n",
174 stateblock->state.render_states[WINED3DRS_SHADEMODE]);
178 static void state_ditherenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
180 if (stateblock->state.render_states[WINED3DRS_DITHERENABLE])
183 checkGLcall("glEnable GL_DITHER");
187 glDisable(GL_DITHER);
188 checkGLcall("glDisable GL_DITHER");
192 static void state_zwritenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
194 /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off.
195 * If yes, this has to be merged with ZENABLE and ZFUNC. */
196 if (stateblock->state.render_states[WINED3DRS_ZWRITEENABLE])
199 checkGLcall("glDepthMask(1)");
204 checkGLcall("glDepthMask(0)");
208 static void state_zfunc(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
210 GLenum depth_func = CompareFunc(stateblock->state.render_states[WINED3DRS_ZFUNC]);
212 if (!depth_func) return;
214 if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL)
217 /* There are a few issues with this: First, our inability to
218 * select a proper Z depth, most of the time we're stuck with
219 * D24S8, even if the app selects D32 or D16. There seem to be
220 * some other precision problems which have to be debugged to
221 * make NOTEQUAL and EQUAL work properly. */
225 FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet.\n");
229 glDepthFunc(depth_func);
230 checkGLcall("glDepthFunc");
233 static void state_ambient(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
236 D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_AMBIENT], col);
238 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
239 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
240 checkGLcall("glLightModel for MODEL_AMBIENT");
243 static void state_blend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
245 struct wined3d_surface *target = stateblock->device->render_targets[0];
246 const struct wined3d_gl_info *gl_info = context->gl_info;
247 int srcBlend = GL_ZERO;
248 int dstBlend = GL_ZERO;
250 /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
251 * blending parameters to work. */
252 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE]
253 || stateblock->state.render_states[WINED3DRS_EDGEANTIALIAS]
254 || stateblock->state.render_states[WINED3DRS_ANTIALIASEDLINEENABLE])
256 /* Disable blending in all cases even without pixelshaders.
257 * With blending on we could face a big performance penalty.
258 * The d3d9 visual test confirms the behavior. */
259 if (context->render_offscreen
260 && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
263 checkGLcall("glDisable GL_BLEND");
267 checkGLcall("glEnable GL_BLEND");
271 checkGLcall("glDisable GL_BLEND");
272 /* Nothing more to do - get out */
276 switch (stateblock->state.render_states[WINED3DRS_DESTBLEND])
278 case WINED3DBLEND_ZERO : dstBlend = GL_ZERO; break;
279 case WINED3DBLEND_ONE : dstBlend = GL_ONE; break;
280 case WINED3DBLEND_SRCCOLOR : dstBlend = GL_SRC_COLOR; break;
281 case WINED3DBLEND_INVSRCCOLOR : dstBlend = GL_ONE_MINUS_SRC_COLOR; break;
282 case WINED3DBLEND_SRCALPHA : dstBlend = GL_SRC_ALPHA; break;
283 case WINED3DBLEND_INVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA; break;
284 case WINED3DBLEND_DESTCOLOR : dstBlend = GL_DST_COLOR; break;
285 case WINED3DBLEND_INVDESTCOLOR : dstBlend = GL_ONE_MINUS_DST_COLOR; break;
287 /* To compensate the lack of format switching with backbuffer offscreen rendering,
288 * and with onscreen rendering, we modify the alpha test parameters for (INV)DESTALPHA
289 * if the render target doesn't support alpha blending. A nonexistent alpha channel
290 * returns 1.0, so D3DBLEND_DESTALPHA is GL_ONE, and D3DBLEND_INVDESTALPHA is GL_ZERO
292 case WINED3DBLEND_DESTALPHA :
293 dstBlend = target->resource.format->alpha_mask ? GL_DST_ALPHA : GL_ONE;
295 case WINED3DBLEND_INVDESTALPHA :
296 dstBlend = target->resource.format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
299 case WINED3DBLEND_SRCALPHASAT :
300 dstBlend = GL_SRC_ALPHA_SATURATE;
301 WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
304 /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
305 * values which are still valid up to d3d9. They should not occur as dest blend values
307 case WINED3DBLEND_BOTHSRCALPHA : dstBlend = GL_SRC_ALPHA;
308 srcBlend = GL_SRC_ALPHA;
309 FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
312 case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
313 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
314 FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
317 case WINED3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR_EXT; break;
318 case WINED3DBLEND_INVBLENDFACTOR : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR_EXT; break;
320 FIXME("Unrecognized dst blend value %#x.\n",
321 stateblock->state.render_states[WINED3DRS_DESTBLEND]);
324 switch (stateblock->state.render_states[WINED3DRS_SRCBLEND])
326 case WINED3DBLEND_ZERO : srcBlend = GL_ZERO; break;
327 case WINED3DBLEND_ONE : srcBlend = GL_ONE; break;
328 case WINED3DBLEND_SRCCOLOR : srcBlend = GL_SRC_COLOR; break;
329 case WINED3DBLEND_INVSRCCOLOR : srcBlend = GL_ONE_MINUS_SRC_COLOR; break;
330 case WINED3DBLEND_SRCALPHA : srcBlend = GL_SRC_ALPHA; break;
331 case WINED3DBLEND_INVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA; break;
332 case WINED3DBLEND_DESTCOLOR : srcBlend = GL_DST_COLOR; break;
333 case WINED3DBLEND_INVDESTCOLOR : srcBlend = GL_ONE_MINUS_DST_COLOR; break;
334 case WINED3DBLEND_SRCALPHASAT : srcBlend = GL_SRC_ALPHA_SATURATE; break;
336 case WINED3DBLEND_DESTALPHA :
337 srcBlend = target->resource.format->alpha_mask ? GL_DST_ALPHA : GL_ONE;
339 case WINED3DBLEND_INVDESTALPHA :
340 srcBlend = target->resource.format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
343 case WINED3DBLEND_BOTHSRCALPHA : srcBlend = GL_SRC_ALPHA;
344 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
347 case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
348 dstBlend = GL_SRC_ALPHA;
351 case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR_EXT; break;
352 case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR_EXT; break;
354 FIXME("Unrecognized src blend value %#x.\n",
355 stateblock->state.render_states[WINED3DRS_SRCBLEND]);
358 if (stateblock->state.render_states[WINED3DRS_EDGEANTIALIAS]
359 || stateblock->state.render_states[WINED3DRS_ANTIALIASEDLINEENABLE])
361 glEnable(GL_LINE_SMOOTH);
362 checkGLcall("glEnable(GL_LINE_SMOOTH)");
363 if(srcBlend != GL_SRC_ALPHA) {
364 WARN("WINED3DRS_EDGEANTIALIAS enabled, but unexpected src blending param\n");
366 if(dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE) {
367 WARN("WINED3DRS_EDGEANTIALIAS enabled, but unexpected dst blending param\n");
370 glDisable(GL_LINE_SMOOTH);
371 checkGLcall("glDisable(GL_LINE_SMOOTH)");
374 /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
375 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_BLENDOP))) {
376 state_blendop(STATE_RENDER(WINED3DRS_BLENDOPALPHA), stateblock, context);
379 if (stateblock->state.render_states[WINED3DRS_SEPARATEALPHABLENDENABLE])
381 int srcBlendAlpha = GL_ZERO;
382 int dstBlendAlpha = GL_ZERO;
384 /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
385 if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
387 WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
391 switch (stateblock->state.render_states[WINED3DRS_DESTBLENDALPHA])
393 case WINED3DBLEND_ZERO : dstBlendAlpha = GL_ZERO; break;
394 case WINED3DBLEND_ONE : dstBlendAlpha = GL_ONE; break;
395 case WINED3DBLEND_SRCCOLOR : dstBlendAlpha = GL_SRC_COLOR; break;
396 case WINED3DBLEND_INVSRCCOLOR : dstBlendAlpha = GL_ONE_MINUS_SRC_COLOR; break;
397 case WINED3DBLEND_SRCALPHA : dstBlendAlpha = GL_SRC_ALPHA; break;
398 case WINED3DBLEND_INVSRCALPHA : dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; break;
399 case WINED3DBLEND_DESTCOLOR : dstBlendAlpha = GL_DST_COLOR; break;
400 case WINED3DBLEND_INVDESTCOLOR : dstBlendAlpha = GL_ONE_MINUS_DST_COLOR; break;
401 case WINED3DBLEND_DESTALPHA : dstBlendAlpha = GL_DST_ALPHA; break;
402 case WINED3DBLEND_INVDESTALPHA : dstBlendAlpha = GL_DST_ALPHA; break;
403 case WINED3DBLEND_SRCALPHASAT :
404 dstBlend = GL_SRC_ALPHA_SATURATE;
405 WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
407 /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
408 * values which are still valid up to d3d9. They should not occur as dest blend values
410 case WINED3DBLEND_BOTHSRCALPHA :
411 dstBlendAlpha = GL_SRC_ALPHA;
412 srcBlendAlpha = GL_SRC_ALPHA;
413 FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
415 case WINED3DBLEND_BOTHINVSRCALPHA :
416 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
417 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
418 FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
420 case WINED3DBLEND_BLENDFACTOR : dstBlendAlpha = GL_CONSTANT_COLOR_EXT; break;
421 case WINED3DBLEND_INVBLENDFACTOR : dstBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR_EXT; break;
423 FIXME("Unrecognized dst blend alpha value %#x.\n",
424 stateblock->state.render_states[WINED3DRS_DESTBLENDALPHA]);
427 switch (stateblock->state.render_states[WINED3DRS_SRCBLENDALPHA])
429 case WINED3DBLEND_ZERO : srcBlendAlpha = GL_ZERO; break;
430 case WINED3DBLEND_ONE : srcBlendAlpha = GL_ONE; break;
431 case WINED3DBLEND_SRCCOLOR : srcBlendAlpha = GL_SRC_COLOR; break;
432 case WINED3DBLEND_INVSRCCOLOR : srcBlendAlpha = GL_ONE_MINUS_SRC_COLOR; break;
433 case WINED3DBLEND_SRCALPHA : srcBlendAlpha = GL_SRC_ALPHA; break;
434 case WINED3DBLEND_INVSRCALPHA : srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; break;
435 case WINED3DBLEND_DESTCOLOR : srcBlendAlpha = GL_DST_COLOR; break;
436 case WINED3DBLEND_INVDESTCOLOR : srcBlendAlpha = GL_ONE_MINUS_DST_COLOR; break;
437 case WINED3DBLEND_SRCALPHASAT : srcBlendAlpha = GL_SRC_ALPHA_SATURATE; break;
438 case WINED3DBLEND_DESTALPHA : srcBlendAlpha = GL_DST_ALPHA; break;
439 case WINED3DBLEND_INVDESTALPHA : srcBlendAlpha = GL_DST_ALPHA; break;
440 case WINED3DBLEND_BOTHSRCALPHA :
441 srcBlendAlpha = GL_SRC_ALPHA;
442 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
444 case WINED3DBLEND_BOTHINVSRCALPHA :
445 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
446 dstBlendAlpha = GL_SRC_ALPHA;
448 case WINED3DBLEND_BLENDFACTOR : srcBlendAlpha = GL_CONSTANT_COLOR_EXT; break;
449 case WINED3DBLEND_INVBLENDFACTOR : srcBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR_EXT; break;
451 FIXME("Unrecognized src blend alpha value %#x.\n",
452 stateblock->state.render_states[WINED3DRS_SRCBLENDALPHA]);
455 GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
456 checkGLcall("glBlendFuncSeparateEXT");
458 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
459 glBlendFunc(srcBlend, dstBlend);
460 checkGLcall("glBlendFunc");
463 /* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state,
464 so it may need updating */
465 if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE])
466 stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
469 static void state_blendfactor_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
471 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
474 static void state_blendfactor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
476 const struct wined3d_gl_info *gl_info = context->gl_info;
479 TRACE("Setting blend factor to %#x.\n", stateblock->state.render_states[WINED3DRS_BLENDFACTOR]);
480 D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_BLENDFACTOR], col);
481 GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
482 checkGLcall("glBlendColor");
485 static void state_alpha(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
489 BOOL enable_ckey = FALSE;
491 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
493 /* Find out if the texture on the first stage has a ckey set
494 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
495 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
496 * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
497 * in case it finds some texture+colorkeyenable combination which needs extra care.
499 if (stateblock->state.textures[0])
501 struct wined3d_texture *texture = stateblock->state.textures[0];
502 GLenum texture_dimensions = texture->target;
504 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
506 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
508 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
510 /* The surface conversion does not do color keying conversion for surfaces that have an alpha
511 * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
512 * surface has alpha bits */
513 if (!surf->resource.format->alpha_mask) enable_ckey = TRUE;
518 if (enable_ckey || context->last_was_ckey)
519 stateblock_apply_state(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
520 context->last_was_ckey = enable_ckey;
522 if (stateblock->state.render_states[WINED3DRS_ALPHATESTENABLE]
523 || (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && enable_ckey))
525 glEnable(GL_ALPHA_TEST);
526 checkGLcall("glEnable GL_ALPHA_TEST");
528 glDisable(GL_ALPHA_TEST);
529 checkGLcall("glDisable GL_ALPHA_TEST");
530 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
536 if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && enable_ckey)
538 glParm = GL_NOTEQUAL;
541 ref = ((float)stateblock->state.render_states[WINED3DRS_ALPHAREF]) / 255.0f;
542 glParm = CompareFunc(stateblock->state.render_states[WINED3DRS_ALPHAFUNC]);
545 glAlphaFunc(glParm, ref);
546 checkGLcall("glAlphaFunc");
550 static void state_clipping(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
552 const struct wined3d_gl_info *gl_info = context->gl_info;
553 const struct wined3d_state *state = &stateblock->state;
554 DWORD enable = 0xFFFFFFFF;
555 DWORD disable = 0x00000000;
557 if (!stateblock->device->vs_clipping && use_vs(state))
559 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
560 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
561 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
562 * of that - don't do anything here and keep them disabled
564 if (state->render_states[WINED3DRS_CLIPPLANEENABLE])
566 static BOOL warned = FALSE;
568 FIXME("Clipping not supported with vertex shaders\n");
575 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
576 * of already set values
579 /* If enabling / disabling all
580 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
582 if (state->render_states[WINED3DRS_CLIPPING])
584 enable = state->render_states[WINED3DRS_CLIPPLANEENABLE];
585 disable = ~state->render_states[WINED3DRS_CLIPPLANEENABLE];
586 if (gl_info->supported[ARB_DEPTH_CLAMP])
588 glDisable(GL_DEPTH_CLAMP);
589 checkGLcall("glDisable(GL_DEPTH_CLAMP)");
592 disable = 0xffffffff;
594 if (gl_info->supported[ARB_DEPTH_CLAMP])
596 glEnable(GL_DEPTH_CLAMP);
597 checkGLcall("glEnable(GL_DEPTH_CLAMP)");
601 FIXME("Clipping disabled, but ARB_depth_clamp isn't supported.\n");
605 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
606 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
607 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
608 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
609 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
610 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
612 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
613 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
614 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
615 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
616 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
617 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
619 /** update clipping status */
622 stateblock->state.clip_status.ClipUnion = 0;
623 stateblock->state.clip_status.ClipIntersection = 0xFFFFFFFF;
627 stateblock->state.clip_status.ClipUnion = 0;
628 stateblock->state.clip_status.ClipIntersection = 0;
632 static void state_blendop_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
634 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
637 static GLenum gl_blend_op(WINED3DBLENDOP op)
641 case WINED3DBLENDOP_ADD:
642 return GL_FUNC_ADD_EXT;
643 case WINED3DBLENDOP_SUBTRACT:
644 return GL_FUNC_SUBTRACT_EXT;
645 case WINED3DBLENDOP_REVSUBTRACT:
646 return GL_FUNC_REVERSE_SUBTRACT_EXT;
647 case WINED3DBLENDOP_MIN:
649 case WINED3DBLENDOP_MAX:
652 FIXME("Unhandled blend op %#x.\n", op);
657 static void state_blendop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
659 const struct wined3d_gl_info *gl_info = context->gl_info;
660 int blendEquation = GL_FUNC_ADD_EXT;
661 int blendEquationAlpha = GL_FUNC_ADD_EXT;
663 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
664 if (stateblock->state.render_states[WINED3DRS_BLENDOPALPHA]
665 && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
667 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
671 blendEquation = gl_blend_op(stateblock->state.render_states[WINED3DRS_BLENDOP]);
672 blendEquationAlpha = gl_blend_op(stateblock->state.render_states[WINED3DRS_BLENDOPALPHA]);
674 if (stateblock->state.render_states[WINED3DRS_SEPARATEALPHABLENDENABLE])
676 TRACE("glBlendEquationSeparateEXT(%x, %x)\n", blendEquation, blendEquationAlpha);
677 GL_EXTCALL(glBlendEquationSeparateEXT(blendEquation, blendEquationAlpha));
678 checkGLcall("glBlendEquationSeparateEXT");
680 TRACE("glBlendEquation(%x)\n", blendEquation);
681 GL_EXTCALL(glBlendEquationEXT(blendEquation));
682 checkGLcall("glBlendEquation");
686 static void state_specularenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
688 const struct wined3d_gl_info *gl_info = context->gl_info;
689 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
690 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
691 * specular color. This is wrong:
692 * Separate specular color means the specular colour is maintained separately, whereas
693 * single color means it is merged in. However in both cases they are being used to
695 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
696 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
700 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
701 * Instead, we need to setup the FinalCombiner properly.
703 * The default setup for the FinalCombiner is:
705 * <variable> <input> <mapping> <usage>
706 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
707 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
708 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
709 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
710 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
711 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
712 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
714 * That's pretty much fine as it is, except for variable B, which needs to take
715 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
716 * whether WINED3DRS_SPECULARENABLE is enabled or not.
719 TRACE("Setting specular enable state and materials\n");
720 if (stateblock->state.render_states[WINED3DRS_SPECULARENABLE])
722 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&stateblock->state.material.Specular);
723 checkGLcall("glMaterialfv");
725 if (stateblock->state.material.Power > gl_info->limits.shininess)
727 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
728 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
729 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
730 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
731 * them, it should be safe to do so without major visual distortions.
733 WARN("Material power = %f, limit %f\n", stateblock->state.material.Power, gl_info->limits.shininess);
734 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
738 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, stateblock->state.material.Power);
740 checkGLcall("glMaterialf(GL_SHININESS)");
742 if (gl_info->supported[EXT_SECONDARY_COLOR])
744 glEnable(GL_COLOR_SUM_EXT);
748 TRACE("Specular colors cannot be enabled in this version of opengl\n");
750 checkGLcall("glEnable(GL_COLOR_SUM)");
752 if (gl_info->supported[NV_REGISTER_COMBINERS])
754 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
755 checkGLcall("glFinalCombinerInputNV()");
758 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
760 /* for the case of enabled lighting: */
761 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
762 checkGLcall("glMaterialfv");
764 /* for the case of disabled lighting: */
765 if (gl_info->supported[EXT_SECONDARY_COLOR])
767 glDisable(GL_COLOR_SUM_EXT);
771 TRACE("Specular colors cannot be disabled in this version of opengl\n");
773 checkGLcall("glDisable(GL_COLOR_SUM)");
775 if (gl_info->supported[NV_REGISTER_COMBINERS])
777 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
778 checkGLcall("glFinalCombinerInputNV()");
782 TRACE("(%p) : Diffuse {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device,
783 stateblock->state.material.Diffuse.r, stateblock->state.material.Diffuse.g,
784 stateblock->state.material.Diffuse.b, stateblock->state.material.Diffuse.a);
785 TRACE("(%p) : Ambient {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device,
786 stateblock->state.material.Ambient.r, stateblock->state.material.Ambient.g,
787 stateblock->state.material.Ambient.b, stateblock->state.material.Ambient.a);
788 TRACE("(%p) : Specular {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device,
789 stateblock->state.material.Specular.r, stateblock->state.material.Specular.g,
790 stateblock->state.material.Specular.b, stateblock->state.material.Specular.a);
791 TRACE("(%p) : Emissive {%.8e, %.8e, %.8e, %.8e}\n", stateblock->device,
792 stateblock->state.material.Emissive.r, stateblock->state.material.Emissive.g,
793 stateblock->state.material.Emissive.b, stateblock->state.material.Emissive.a);
795 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&stateblock->state.material.Ambient);
796 checkGLcall("glMaterialfv(GL_AMBIENT)");
797 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&stateblock->state.material.Diffuse);
798 checkGLcall("glMaterialfv(GL_DIFFUSE)");
799 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&stateblock->state.material.Emissive);
800 checkGLcall("glMaterialfv(GL_EMISSION)");
803 static void state_texfactor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
805 const struct wined3d_gl_info *gl_info = context->gl_info;
808 /* Note the texture color applies to all textures whereas
809 * GL_TEXTURE_ENV_COLOR applies to active only
812 D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_TEXTUREFACTOR], col);
814 /* And now the default texture color as well */
815 for (i = 0; i < gl_info->limits.texture_stages; ++i)
817 /* Note the WINED3DRS value applies to all textures, but GL has one
818 * per texture, so apply it now ready to be used!
820 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
821 checkGLcall("glActiveTextureARB");
823 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
824 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
828 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
829 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
831 const struct wined3d_gl_info *gl_info = context->gl_info;
833 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
834 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
835 GL_EXTCALL(glActiveStencilFaceEXT(face));
836 checkGLcall("glActiveStencilFaceEXT(...)");
837 glStencilFunc(func, ref, mask);
838 checkGLcall("glStencilFunc(...)");
839 glStencilOp(stencilFail, depthFail, stencilPass);
840 checkGLcall("glStencilOp(...)");
843 static void state_stencil(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
845 const struct wined3d_gl_info *gl_info = context->gl_info;
846 DWORD onesided_enable = FALSE;
847 DWORD twosided_enable = FALSE;
848 GLint func = GL_ALWAYS;
849 GLint func_ccw = GL_ALWAYS;
852 GLint stencilFail = GL_KEEP;
853 GLint depthFail = GL_KEEP;
854 GLint stencilPass = GL_KEEP;
855 GLint stencilFail_ccw = GL_KEEP;
856 GLint depthFail_ccw = GL_KEEP;
857 GLint stencilPass_ccw = GL_KEEP;
859 /* No stencil test without a stencil buffer. */
860 if (!stateblock->device->depth_stencil)
862 glDisable(GL_STENCIL_TEST);
863 checkGLcall("glDisable GL_STENCIL_TEST");
867 onesided_enable = stateblock->state.render_states[WINED3DRS_STENCILENABLE];
868 twosided_enable = stateblock->state.render_states[WINED3DRS_TWOSIDEDSTENCILMODE];
869 if (!(func = CompareFunc(stateblock->state.render_states[WINED3DRS_STENCILFUNC])))
871 if (!(func_ccw = CompareFunc(stateblock->state.render_states[WINED3DRS_CCW_STENCILFUNC])))
872 func_ccw = GL_ALWAYS;
873 ref = stateblock->state.render_states[WINED3DRS_STENCILREF];
874 mask = stateblock->state.render_states[WINED3DRS_STENCILMASK];
875 stencilFail = StencilOp(stateblock->state.render_states[WINED3DRS_STENCILFAIL]);
876 depthFail = StencilOp(stateblock->state.render_states[WINED3DRS_STENCILZFAIL]);
877 stencilPass = StencilOp(stateblock->state.render_states[WINED3DRS_STENCILPASS]);
878 stencilFail_ccw = StencilOp(stateblock->state.render_states[WINED3DRS_CCW_STENCILFAIL]);
879 depthFail_ccw = StencilOp(stateblock->state.render_states[WINED3DRS_CCW_STENCILZFAIL]);
880 stencilPass_ccw = StencilOp(stateblock->state.render_states[WINED3DRS_CCW_STENCILPASS]);
882 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
883 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
884 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
885 onesided_enable, twosided_enable, ref, mask,
886 func, stencilFail, depthFail, stencilPass,
887 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
889 if (twosided_enable && onesided_enable) {
890 glEnable(GL_STENCIL_TEST);
891 checkGLcall("glEnable GL_STENCIL_TEST");
893 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
895 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
896 * which has an effect on the code below too. If we apply the front face
897 * afterwards, we are sure that the active stencil face is set to front,
898 * and other stencil functions which do not use two sided stencil do not have
901 renderstate_stencil_twosided(context, GL_BACK,
902 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
903 renderstate_stencil_twosided(context, GL_FRONT,
904 func, ref, mask, stencilFail, depthFail, stencilPass);
906 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
908 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
909 checkGLcall("glStencilFuncSeparateATI(...)");
910 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
911 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
912 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
913 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
915 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
918 else if(onesided_enable)
920 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
922 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
923 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
926 /* This code disables the ATI extension as well, since the standard stencil functions are equal
927 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
929 glEnable(GL_STENCIL_TEST);
930 checkGLcall("glEnable GL_STENCIL_TEST");
931 glStencilFunc(func, ref, mask);
932 checkGLcall("glStencilFunc(...)");
933 glStencilOp(stencilFail, depthFail, stencilPass);
934 checkGLcall("glStencilOp(...)");
936 glDisable(GL_STENCIL_TEST);
937 checkGLcall("glDisable GL_STENCIL_TEST");
941 static void state_stencilwrite2s(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
943 DWORD mask = stateblock->device->depth_stencil ? stateblock->state.render_states[WINED3DRS_STENCILWRITEMASK] : 0;
944 const struct wined3d_gl_info *gl_info = context->gl_info;
946 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
947 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
949 checkGLcall("glStencilMask");
950 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
951 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
955 static void state_stencilwrite(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
957 DWORD mask = stateblock->device->depth_stencil ? stateblock->state.render_states[WINED3DRS_STENCILWRITEMASK] : 0;
960 checkGLcall("glStencilMask");
963 static void state_fog_vertexpart(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
966 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
968 if (!stateblock->state.render_states[WINED3DRS_FOGENABLE]) return;
970 /* Table fog on: Never use fog coords, and use per-fragment fog */
971 if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE)
973 glHint(GL_FOG_HINT, GL_NICEST);
974 if(context->fog_coord) {
975 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
976 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
977 context->fog_coord = FALSE;
982 /* Otherwise use per-vertex fog in any case */
983 glHint(GL_FOG_HINT, GL_FASTEST);
985 if (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw)
987 /* No fog at all, or transformed vertices: Use fog coord */
988 if(!context->fog_coord) {
989 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
990 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
991 context->fog_coord = TRUE;
994 /* Otherwise, use the fragment depth */
995 if(context->fog_coord) {
996 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
997 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
998 context->fog_coord = FALSE;
1003 void state_fogstartend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1005 float fogstart, fogend;
1011 switch(context->fog_source) {
1017 case FOGSOURCE_COORD:
1023 tmpvalue.d = stateblock->state.render_states[WINED3DRS_FOGSTART];
1024 fogstart = tmpvalue.f;
1025 tmpvalue.d = stateblock->state.render_states[WINED3DRS_FOGEND];
1026 fogend = tmpvalue.f;
1027 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
1028 if(fogstart == fogend) {
1029 fogstart = -1.0f / 0.0f;
1035 /* This should not happen.context->fog_source is set in wined3d, not the app.
1036 * Still this is needed to make the compiler happy
1038 ERR("Unexpected fog coordinate source\n");
1043 glFogf(GL_FOG_START, fogstart);
1044 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1045 TRACE("Fog Start == %f\n", fogstart);
1047 glFogf(GL_FOG_END, fogend);
1048 checkGLcall("glFogf(GL_FOG_END, fogend)");
1049 TRACE("Fog End == %f\n", fogend);
1052 void state_fog_fragpart(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1054 const struct wined3d_state *state = &stateblock->state;
1055 enum fogsource new_source;
1057 TRACE("state_id %#x, stateblock %p, context %p\n", state_id, stateblock, context);
1059 if (!state->render_states[WINED3DRS_FOGENABLE])
1061 /* No fog? Disable it, and we're done :-) */
1062 glDisableWINE(GL_FOG);
1063 checkGLcall("glDisable GL_FOG");
1069 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1070 * It can use the Z value of the vertex, or the alpha component of the specular color.
1071 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1072 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1073 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1075 * FOGTABLEMODE != NONE:
1076 * The Z value is used, with the equation specified, no matter what vertex type.
1078 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1079 * Per vertex fog is calculated using the specified fog equation and the parameters
1081 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1082 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1083 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1086 * Rules for vertex fog with shaders:
1088 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1089 * the fog computation to happen during transformation while openGL expects it to happen
1090 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1091 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1092 * To solve this problem, WineD3D does:
1093 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1095 * and 2) disables the fog computation (in either the fixed function or programmable
1096 * rasterizer) if using a vertex program.
1098 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1099 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1100 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1101 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1102 * There are some GL differences between specular fog coords and vertex shaders though.
1104 * With table fog the vertex shader fog coordinate is ignored.
1106 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1110 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1111 * the system will apply only pixel(=table) fog effects."
1113 if (state->render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
1117 glFogi(GL_FOG_MODE, GL_LINEAR);
1118 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1119 new_source = FOGSOURCE_VS;
1123 switch (state->render_states[WINED3DRS_FOGVERTEXMODE])
1125 /* If processed vertices are used, fall through to the NONE case */
1126 case WINED3DFOG_EXP:
1127 if(!context->last_was_rhw) {
1128 glFogi(GL_FOG_MODE, GL_EXP);
1129 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1130 new_source = FOGSOURCE_FFP;
1135 case WINED3DFOG_EXP2:
1136 if(!context->last_was_rhw) {
1137 glFogi(GL_FOG_MODE, GL_EXP2);
1138 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1139 new_source = FOGSOURCE_FFP;
1144 case WINED3DFOG_LINEAR:
1145 if(!context->last_was_rhw) {
1146 glFogi(GL_FOG_MODE, GL_LINEAR);
1147 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1148 new_source = FOGSOURCE_FFP;
1153 case WINED3DFOG_NONE:
1154 /* Both are none? According to msdn the alpha channel of the specular
1155 * color contains a fog factor. Set it in drawStridedSlow.
1156 * Same happens with Vertexfog on transformed vertices
1158 new_source = FOGSOURCE_COORD;
1159 glFogi(GL_FOG_MODE, GL_LINEAR);
1160 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1164 FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %#x.\n",
1165 state->render_states[WINED3DRS_FOGVERTEXMODE]);
1166 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1170 new_source = FOGSOURCE_FFP;
1172 switch (state->render_states[WINED3DRS_FOGTABLEMODE])
1174 case WINED3DFOG_EXP:
1175 glFogi(GL_FOG_MODE, GL_EXP);
1176 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1179 case WINED3DFOG_EXP2:
1180 glFogi(GL_FOG_MODE, GL_EXP2);
1181 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1184 case WINED3DFOG_LINEAR:
1185 glFogi(GL_FOG_MODE, GL_LINEAR);
1186 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1189 case WINED3DFOG_NONE: /* Won't happen */
1191 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %#x.\n",
1192 state->render_states[WINED3DRS_FOGTABLEMODE]);
1196 glEnableWINE(GL_FOG);
1197 checkGLcall("glEnable GL_FOG");
1198 if(new_source != context->fog_source) {
1199 context->fog_source = new_source;
1200 state_fogstartend(STATE_RENDER(WINED3DRS_FOGSTART), stateblock, context);
1204 static void state_rangefog_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1206 if (stateblock->state.render_states[WINED3DRS_RANGEFOGENABLE])
1207 WARN("Range fog enabled, but not supported by this opengl implementation\n");
1210 static void state_rangefog(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1212 if (stateblock->state.render_states[WINED3DRS_RANGEFOGENABLE])
1214 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1215 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1217 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1218 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1222 void state_fogcolor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1225 D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_FOGCOLOR], col);
1226 glFogfv(GL_FOG_COLOR, &col[0]);
1227 checkGLcall("glFog GL_FOG_COLOR");
1230 void state_fogdensity(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1236 tmpvalue.d = stateblock->state.render_states[WINED3DRS_FOGDENSITY];
1237 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1238 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1241 static void state_colormat(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1243 const struct wined3d_state *state = &stateblock->state;
1244 IWineD3DDeviceImpl *device = stateblock->device;
1247 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1248 * The vertex declaration will call this function if the fixed function pipeline is used.
1251 if(isStateDirty(context, STATE_VDECL)) {
1255 context->num_untracked_materials = 0;
1256 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1257 && state->render_states[WINED3DRS_COLORVERTEX])
1259 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1260 state->render_states[WINED3DRS_DIFFUSEMATERIALSOURCE],
1261 state->render_states[WINED3DRS_AMBIENTMATERIALSOURCE],
1262 state->render_states[WINED3DRS_EMISSIVEMATERIALSOURCE],
1263 state->render_states[WINED3DRS_SPECULARMATERIALSOURCE]);
1265 if (state->render_states[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1)
1267 if (state->render_states[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1)
1268 Parm = GL_AMBIENT_AND_DIFFUSE;
1271 if (state->render_states[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1)
1273 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1274 context->num_untracked_materials++;
1276 if (state->render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1)
1278 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1279 context->num_untracked_materials++;
1282 else if (state->render_states[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1)
1285 if (state->render_states[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1)
1287 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1288 context->num_untracked_materials++;
1290 if (state->render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1)
1292 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1293 context->num_untracked_materials++;
1296 else if (state->render_states[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1)
1299 if (state->render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1)
1301 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1302 context->num_untracked_materials++;
1305 else if (state->render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1)
1311 /* Nothing changed, return. */
1312 if (Parm == context->tracking_parm) return;
1315 glDisable(GL_COLOR_MATERIAL);
1316 checkGLcall("glDisable GL_COLOR_MATERIAL");
1318 glColorMaterial(GL_FRONT_AND_BACK, Parm);
1319 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1320 glEnable(GL_COLOR_MATERIAL);
1321 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1324 /* Apparently calls to glMaterialfv are ignored for properties we're
1325 * tracking with glColorMaterial, so apply those here. */
1326 switch (context->tracking_parm) {
1327 case GL_AMBIENT_AND_DIFFUSE:
1328 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.Ambient);
1329 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.Diffuse);
1330 checkGLcall("glMaterialfv");
1334 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.Diffuse);
1335 checkGLcall("glMaterialfv");
1339 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.Ambient);
1340 checkGLcall("glMaterialfv");
1344 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.Emissive);
1345 checkGLcall("glMaterialfv");
1349 /* Only change material color if specular is enabled, otherwise it is set to black */
1350 if (state->render_states[WINED3DRS_SPECULARENABLE])
1352 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.Specular);
1353 checkGLcall("glMaterialfv");
1355 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1356 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1357 checkGLcall("glMaterialfv");
1362 context->tracking_parm = Parm;
1365 static void state_linepattern(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1369 WINED3DLINEPATTERN lp;
1371 tmppattern.d = stateblock->state.render_states[WINED3DRS_LINEPATTERN];
1373 TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1375 if (tmppattern.lp.wRepeatFactor) {
1376 glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1377 checkGLcall("glLineStipple(repeat, linepattern)");
1378 glEnable(GL_LINE_STIPPLE);
1379 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1381 glDisable(GL_LINE_STIPPLE);
1382 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1386 static void state_normalize(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1388 if(isStateDirty(context, STATE_VDECL)) {
1391 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1392 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1393 * by zero and is not properly defined in opengl, so avoid it
1395 if (stateblock->state.render_states[WINED3DRS_NORMALIZENORMALS]
1396 && (stateblock->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1398 glEnable(GL_NORMALIZE);
1399 checkGLcall("glEnable(GL_NORMALIZE);");
1401 glDisable(GL_NORMALIZE);
1402 checkGLcall("glDisable(GL_NORMALIZE);");
1406 static void state_psizemin_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1413 tmpvalue.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MIN];
1414 if (tmpvalue.f != 1.0f)
1416 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1418 tmpvalue.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MAX];
1419 if (tmpvalue.f != 64.0f)
1421 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1426 static void state_psizemin_ext(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1428 const struct wined3d_gl_info *gl_info = context->gl_info;
1435 min.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MIN];
1436 max.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MAX];
1438 /* Max point size trumps min point size */
1443 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1444 checkGLcall("glPointParameterfEXT(...)");
1445 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1446 checkGLcall("glPointParameterfEXT(...)");
1449 static void state_psizemin_arb(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1451 const struct wined3d_gl_info *gl_info = context->gl_info;
1458 min.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MIN];
1459 max.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MAX];
1461 /* Max point size trumps min point size */
1466 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1467 checkGLcall("glPointParameterfARB(...)");
1468 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1469 checkGLcall("glPointParameterfARB(...)");
1472 static void state_pscale(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1474 const struct wined3d_gl_info *gl_info = context->gl_info;
1475 /* TODO: Group this with the viewport */
1477 * POINTSCALEENABLE controls how point size value is treated. If set to
1478 * true, the point size is scaled with respect to height of viewport.
1479 * When set to false point size is in pixels.
1482 /* Default values */
1483 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1487 } pointSize, A, B, C;
1489 pointSize.d = stateblock->state.render_states[WINED3DRS_POINTSIZE];
1490 A.d = stateblock->state.render_states[WINED3DRS_POINTSCALE_A];
1491 B.d = stateblock->state.render_states[WINED3DRS_POINTSCALE_B];
1492 C.d = stateblock->state.render_states[WINED3DRS_POINTSCALE_C];
1494 if (stateblock->state.render_states[WINED3DRS_POINTSCALEENABLE])
1496 GLfloat scaleFactor;
1497 DWORD h = stateblock->state.viewport.Height;
1499 if (pointSize.f < gl_info->limits.pointsize_min)
1501 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1502 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1503 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1504 * are less than 1.0f. scale_factor = 1.0f / point_size.
1506 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1507 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1508 * is 1.0, but then accepts points below that and draws too small points
1510 pointSize.f = gl_info->limits.pointsize_min;
1512 else if(pointSize.f > gl_info->limits.pointsize_max)
1514 /* gl already scales the input to glPointSize,
1515 * d3d scales the result after the point size scale.
1516 * If the point size is bigger than the max size, use the
1517 * scaling to scale it bigger, and set the gl point size to max
1519 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1520 TRACE("scale: %f\n", scaleFactor);
1521 pointSize.f = gl_info->limits.pointsize_max;
1525 scaleFactor = powf(h * scaleFactor, 2);
1527 att[0] = A.f / scaleFactor;
1528 att[1] = B.f / scaleFactor;
1529 att[2] = C.f / scaleFactor;
1532 if (gl_info->supported[ARB_POINT_PARAMETERS])
1534 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1535 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1537 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1539 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1540 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1542 else if(stateblock->state.render_states[WINED3DRS_POINTSCALEENABLE])
1544 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1547 glPointSize(pointSize.f);
1548 checkGLcall("glPointSize(...);");
1551 static void state_debug_monitor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1553 WARN("token: %#x\n", stateblock->state.render_states[WINED3DRS_DEBUGMONITORTOKEN]);
1556 static void state_colorwrite(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1558 DWORD mask0 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE];
1559 DWORD mask1 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE1];
1560 DWORD mask2 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE2];
1561 DWORD mask3 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE3];
1563 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1564 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1565 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1566 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1567 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1568 glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1569 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1570 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1571 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1572 checkGLcall("glColorMask(...)");
1574 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1575 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1577 FIXME("WINED3DRS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1578 mask0, mask1, mask2, mask3);
1579 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1583 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1585 GL_EXTCALL(glColorMaskIndexedEXT(index,
1586 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1587 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1588 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1589 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1592 static void state_colorwrite0(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1594 set_color_mask(context->gl_info, 0, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE]);
1597 static void state_colorwrite1(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1599 set_color_mask(context->gl_info, 1, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE1]);
1602 static void state_colorwrite2(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1604 set_color_mask(context->gl_info, 2, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE2]);
1607 static void state_colorwrite3(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1609 set_color_mask(context->gl_info, 3, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE3]);
1612 static void state_localviewer(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1614 if (stateblock->state.render_states[WINED3DRS_LOCALVIEWER])
1616 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1617 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1619 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1620 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1624 static void state_lastpixel(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1626 if (stateblock->state.render_states[WINED3DRS_LASTPIXEL])
1628 TRACE("Last Pixel Drawing Enabled\n");
1632 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1635 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1640 static void state_pointsprite_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1644 /* TODO: NV_POINT_SPRITE */
1645 if (!warned && stateblock->state.render_states[WINED3DRS_POINTSPRITEENABLE])
1647 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1648 FIXME("Point sprites not supported\n");
1653 static void state_pointsprite(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1655 const struct wined3d_gl_info *gl_info = context->gl_info;
1656 const struct wined3d_state *state = &stateblock->state;
1658 if (state->render_states[WINED3DRS_POINTSPRITEENABLE])
1662 if (gl_info->limits.point_sprite_units < gl_info->limits.textures && !warned)
1664 if (use_ps(state) || state->lowest_disabled_stage > gl_info->limits.point_sprite_units)
1666 FIXME("The app uses point sprite texture coordinates on more units than supported by the driver\n");
1671 glEnable(GL_POINT_SPRITE_ARB);
1672 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1674 glDisable(GL_POINT_SPRITE_ARB);
1675 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1679 static void state_wrap(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1682 http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1683 http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1684 Discussion on the ways to turn on WRAPing to solve an OpenGL conversion problem.
1685 http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1687 so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1689 if (stateblock->state.render_states[WINED3DRS_WRAP0]
1690 || stateblock->state.render_states[WINED3DRS_WRAP1]
1691 || stateblock->state.render_states[WINED3DRS_WRAP2]
1692 || stateblock->state.render_states[WINED3DRS_WRAP3]
1693 || stateblock->state.render_states[WINED3DRS_WRAP4]
1694 || stateblock->state.render_states[WINED3DRS_WRAP5]
1695 || stateblock->state.render_states[WINED3DRS_WRAP6]
1696 || stateblock->state.render_states[WINED3DRS_WRAP7]
1697 || stateblock->state.render_states[WINED3DRS_WRAP8]
1698 || stateblock->state.render_states[WINED3DRS_WRAP9]
1699 || stateblock->state.render_states[WINED3DRS_WRAP10]
1700 || stateblock->state.render_states[WINED3DRS_WRAP11]
1701 || stateblock->state.render_states[WINED3DRS_WRAP12]
1702 || stateblock->state.render_states[WINED3DRS_WRAP13]
1703 || stateblock->state.render_states[WINED3DRS_WRAP14]
1704 || stateblock->state.render_states[WINED3DRS_WRAP15])
1706 FIXME("(WINED3DRS_WRAP0) Texture wrapping not yet supported.\n");
1710 static void state_msaa_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1712 if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEANTIALIAS])
1713 WARN("Multisample antialiasing not supported by gl\n");
1716 static void state_msaa(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1718 if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEANTIALIAS])
1720 glEnable(GL_MULTISAMPLE_ARB);
1721 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1723 glDisable(GL_MULTISAMPLE_ARB);
1724 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1728 static void state_scissor(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1730 if (stateblock->state.render_states[WINED3DRS_SCISSORTESTENABLE])
1732 glEnable(GL_SCISSOR_TEST);
1733 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1735 glDisable(GL_SCISSOR_TEST);
1736 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1740 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1741 * OpenGL the bias is specified in units of "the smallest value that is
1742 * guaranteed to produce a resolvable offset for a given implementation". To
1743 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1744 * There's no practical way to retrieve that value from a given GL
1745 * implementation, but the D3D application has essentially the same problem,
1746 * which makes a guess of the depth buffer format's highest possible value a
1747 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1748 * depth slope, and doesn't need to be scaled. */
1749 static void state_depthbias(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1751 if (stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS]
1752 || stateblock->state.render_states[WINED3DRS_DEPTHBIAS])
1754 struct wined3d_surface *depth = stateblock->device->depth_stencil;
1761 } scale_bias, const_bias;
1763 scale_bias.d = stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS];
1764 const_bias.d = stateblock->state.render_states[WINED3DRS_DEPTHBIAS];
1766 glEnable(GL_POLYGON_OFFSET_FILL);
1767 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1771 const struct wined3d_format *fmt = depth->resource.format;
1772 scale = powf(2, fmt->depth_size) - 1;
1773 TRACE("Depth format %s, using depthbias scale of %f\n",
1774 debug_d3dformat(fmt->id), scale);
1778 /* The context manager will reapply this state on a depth stencil change */
1779 TRACE("No depth stencil, using depthbias scale of 0.0\n");
1783 glPolygonOffset(scale_bias.f, const_bias.f * scale);
1784 checkGLcall("glPolygonOffset(...)");
1786 glDisable(GL_POLYGON_OFFSET_FILL);
1787 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1791 static void state_zvisible(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1793 if (stateblock->state.render_states[WINED3DRS_ZVISIBLE])
1794 FIXME("WINED3DRS_ZVISIBLE not implemented.\n");
1797 static void state_perspective(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1799 if (stateblock->state.render_states[WINED3DRS_TEXTUREPERSPECTIVE])
1801 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1802 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1804 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1805 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1809 static void state_stippledalpha(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1811 if (stateblock->state.render_states[WINED3DRS_STIPPLEDALPHA])
1812 FIXME(" Stippled Alpha not supported yet.\n");
1815 static void state_antialias(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1817 if (stateblock->state.render_states[WINED3DRS_ANTIALIAS])
1818 FIXME("Antialias not supported yet.\n");
1821 static void state_multisampmask(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1823 if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEMASK] != 0xffffffff)
1824 FIXME("WINED3DRS_MULTISAMPLEMASK %#x not yet implemented.\n",
1825 stateblock->state.render_states[WINED3DRS_MULTISAMPLEMASK]);
1828 static void state_patchedgestyle(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1830 if (stateblock->state.render_states[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
1831 FIXME("WINED3DRS_PATCHEDGESTYLE %#x not yet implemented.\n",
1832 stateblock->state.render_states[WINED3DRS_PATCHEDGESTYLE]);
1835 static void state_patchsegments(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1843 if (stateblock->state.render_states[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1845 static BOOL displayed = FALSE;
1847 tmpvalue.d = stateblock->state.render_states[WINED3DRS_PATCHSEGMENTS];
1849 FIXME("(WINED3DRS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1855 static void state_positiondegree(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1857 if (stateblock->state.render_states[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
1858 FIXME("WINED3DRS_POSITIONDEGREE %#x not yet implemented.\n",
1859 stateblock->state.render_states[WINED3DRS_POSITIONDEGREE]);
1862 static void state_normaldegree(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1864 if (stateblock->state.render_states[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
1865 FIXME("WINED3DRS_NORMALDEGREE %#x not yet implemented.\n",
1866 stateblock->state.render_states[WINED3DRS_NORMALDEGREE]);
1869 static void state_tessellation(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1871 if (stateblock->state.render_states[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1872 FIXME("WINED3DRS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1873 stateblock->state.render_states[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1876 static void state_nvdb(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1883 const struct wined3d_gl_info *gl_info = context->gl_info;
1885 if (stateblock->state.render_states[WINED3DRS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1887 zmin.d = stateblock->state.render_states[WINED3DRS_ADAPTIVETESS_Z];
1888 zmax.d = stateblock->state.render_states[WINED3DRS_ADAPTIVETESS_W];
1890 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1891 * In d3d9 test is not performed in this case*/
1892 if (zmin.f <= zmax.f)
1894 glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1895 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1896 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1897 checkGLcall("glDepthBoundsEXT(...)");
1900 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1901 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1905 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1906 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1909 state_tessellation(state, stateblock, context);
1912 static void state_wrapu(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1914 if (stateblock->state.render_states[WINED3DRS_WRAPU])
1915 FIXME("Render state WINED3DRS_WRAPU not implemented yet.\n");
1918 static void state_wrapv(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1920 if (stateblock->state.render_states[WINED3DRS_WRAPV])
1921 FIXME("Render state WINED3DRS_WRAPV not implemented yet.\n");
1924 static void state_monoenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1926 if (stateblock->state.render_states[WINED3DRS_MONOENABLE])
1927 FIXME("Render state WINED3DRS_MONOENABLE not implemented yet.\n");
1930 static void state_rop2(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1932 if (stateblock->state.render_states[WINED3DRS_ROP2])
1933 FIXME("Render state WINED3DRS_ROP2 not implemented yet.\n");
1936 static void state_planemask(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1938 if (stateblock->state.render_states[WINED3DRS_PLANEMASK])
1939 FIXME("Render state WINED3DRS_PLANEMASK not implemented yet.\n");
1942 static void state_subpixel(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1944 if (stateblock->state.render_states[WINED3DRS_SUBPIXEL])
1945 FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet.\n");
1948 static void state_subpixelx(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1950 if (stateblock->state.render_states[WINED3DRS_SUBPIXELX])
1951 FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet.\n");
1954 static void state_stippleenable(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1956 if (stateblock->state.render_states[WINED3DRS_STIPPLEENABLE])
1957 FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet.\n");
1960 static void state_mipmaplodbias(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1962 if (stateblock->state.render_states[WINED3DRS_MIPMAPLODBIAS])
1963 FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet.\n");
1966 static void state_anisotropy(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1968 if (stateblock->state.render_states[WINED3DRS_ANISOTROPY])
1969 FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet.\n");
1972 static void state_flushbatch(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1974 if (stateblock->state.render_states[WINED3DRS_FLUSHBATCH])
1975 FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet.\n");
1978 static void state_translucentsi(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1980 if (stateblock->state.render_states[WINED3DRS_TRANSLUCENTSORTINDEPENDENT])
1981 FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
1984 static void state_extents(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1986 if (stateblock->state.render_states[WINED3DRS_EXTENTS])
1987 FIXME("Render state WINED3DRS_EXTENTS not implemented yet.\n");
1990 static void state_ckeyblend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1992 if (stateblock->state.render_states[WINED3DRS_COLORKEYBLENDENABLE])
1993 FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet.\n");
1996 static void state_swvp(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
1998 if (stateblock->state.render_states[WINED3DRS_SOFTWAREVERTEXPROCESSING])
1999 FIXME("Software vertex processing not implemented.\n");
2002 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
2003 #if defined (GL_VERSION_1_3)
2004 # define useext(A) A
2005 #elif defined (GL_EXT_texture_env_combine)
2006 # define useext(A) A##_EXT
2007 #elif defined (GL_ARB_texture_env_combine)
2008 # define useext(A) A##_ARB
2011 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2012 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2013 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2014 * flag specifies the complement of the input should be used. */
2015 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2016 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2018 /* Calculate the operand */
2020 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2021 else *operand = GL_ONE_MINUS_SRC_COLOR;
2023 if (from_alpha) *operand = GL_SRC_ALPHA;
2024 else *operand = GL_SRC_COLOR;
2027 /* Calculate the source */
2028 switch (arg & WINED3DTA_SELECTMASK) {
2029 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2030 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2031 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2032 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2033 case WINED3DTA_SPECULAR:
2035 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2036 * 'Secondary color' and isn't supported until base GL supports it
2037 * There is no concept of temp registers as far as I can tell
2039 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2040 *source = GL_TEXTURE;
2043 FIXME("Unrecognized texture arg %#x\n", arg);
2044 *source = GL_TEXTURE;
2049 /* Setup the texture operations texture stage states */
2050 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2051 BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2053 GLenum src1, src2, src3;
2054 GLenum opr1, opr2, opr3;
2056 GLenum src0_target, src1_target, src2_target;
2057 GLenum opr0_target, opr1_target, opr2_target;
2059 GLenum opr=0, invopr, src3_target, opr3_target;
2060 BOOL Handled = FALSE;
2062 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2064 /* This is called by a state handler which has the gl lock held and a context for the thread */
2066 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2067 the form (a1 <operation> a2). However, some of the more complex operations
2068 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2069 in a third parameter called a0. Therefore these are operations of the form
2070 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2072 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2073 functions below, expect their syntax to differ slightly to those listed in the
2074 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2075 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2078 comb_target = useext(GL_COMBINE_ALPHA);
2079 src0_target = useext(GL_SOURCE0_ALPHA);
2080 src1_target = useext(GL_SOURCE1_ALPHA);
2081 src2_target = useext(GL_SOURCE2_ALPHA);
2082 opr0_target = useext(GL_OPERAND0_ALPHA);
2083 opr1_target = useext(GL_OPERAND1_ALPHA);
2084 opr2_target = useext(GL_OPERAND2_ALPHA);
2085 scal_target = GL_ALPHA_SCALE;
2088 comb_target = useext(GL_COMBINE_RGB);
2089 src0_target = useext(GL_SOURCE0_RGB);
2090 src1_target = useext(GL_SOURCE1_RGB);
2091 src2_target = useext(GL_SOURCE2_RGB);
2092 opr0_target = useext(GL_OPERAND0_RGB);
2093 opr1_target = useext(GL_OPERAND1_RGB);
2094 opr2_target = useext(GL_OPERAND2_RGB);
2095 scal_target = useext(GL_RGB_SCALE);
2098 /* If a texture stage references an invalid texture unit the stage just
2099 * passes through the result from the previous stage */
2100 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2102 arg1 = WINED3DTA_CURRENT;
2103 op = WINED3DTOP_SELECTARG1;
2106 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2108 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2110 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2112 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2113 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2115 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2117 Handled = TRUE; /* Assume will be handled */
2119 /* Other texture operations require special extensions: */
2120 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2124 invopr = GL_ONE_MINUS_SRC_ALPHA;
2125 src3_target = GL_SOURCE3_ALPHA_NV;
2126 opr3_target = GL_OPERAND3_ALPHA_NV;
2129 invopr = GL_ONE_MINUS_SRC_COLOR;
2130 src3_target = GL_SOURCE3_RGB_NV;
2131 opr3_target = GL_OPERAND3_RGB_NV;
2134 case WINED3DTOP_DISABLE: /* Only for alpha */
2135 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2136 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2137 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2138 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2139 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2140 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2141 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2142 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2143 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2144 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2145 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2146 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2147 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2148 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2149 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2150 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2151 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2152 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2154 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
2155 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
2156 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2157 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2158 if (op == WINED3DTOP_SELECTARG1) {
2159 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2160 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2161 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2162 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2164 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2165 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2166 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2167 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2169 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2170 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2171 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2172 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2173 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2174 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2175 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2176 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2177 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2178 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2179 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2180 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2183 case WINED3DTOP_MODULATE:
2184 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2185 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2186 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2187 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2188 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2189 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2190 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2191 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2192 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2193 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2194 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2195 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2196 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2197 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2198 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2199 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2200 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2201 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2202 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2203 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2205 case WINED3DTOP_MODULATE2X:
2206 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2207 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2208 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2209 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2210 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2211 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2212 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2213 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2214 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2215 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2216 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2217 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2218 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2219 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2220 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2221 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2222 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2223 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2224 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2225 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2227 case WINED3DTOP_MODULATE4X:
2228 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2229 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2230 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2231 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2232 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2233 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2234 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2235 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2236 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2237 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2238 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2239 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2240 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2241 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2242 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2243 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2244 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2245 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2246 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2247 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2250 case WINED3DTOP_ADD:
2251 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2252 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2253 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2254 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2255 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2256 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2257 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2258 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2259 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2260 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2261 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2262 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2263 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2264 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2265 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2266 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2267 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2268 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2269 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2270 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2273 case WINED3DTOP_ADDSIGNED:
2274 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2275 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2276 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2277 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2278 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2279 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2280 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2281 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2282 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2283 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2284 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2285 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2286 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2287 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2288 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2289 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2290 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2291 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2292 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2293 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2296 case WINED3DTOP_ADDSIGNED2X:
2297 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2298 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2299 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2300 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2301 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2302 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2303 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2304 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2305 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2306 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2307 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2308 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2309 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2310 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2311 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2312 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2313 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2314 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2315 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2316 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2319 case WINED3DTOP_ADDSMOOTH:
2320 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2321 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2322 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2323 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2324 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2325 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2326 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2327 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2328 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2329 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2330 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2331 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2332 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2333 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2334 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2335 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2337 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2338 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2339 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2340 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2342 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2343 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2344 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2345 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2348 case WINED3DTOP_BLENDDIFFUSEALPHA:
2349 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2350 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2351 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2352 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2353 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2354 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2355 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
2356 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
2357 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2358 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2359 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2360 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2361 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2362 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2363 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
2364 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
2365 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2366 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2367 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2368 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2370 case WINED3DTOP_BLENDTEXTUREALPHA:
2371 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2372 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2373 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2374 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2375 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2376 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2377 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2378 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2379 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2380 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2381 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2382 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2383 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2384 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2385 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2386 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2387 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2388 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2389 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2390 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2392 case WINED3DTOP_BLENDFACTORALPHA:
2393 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2394 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2395 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2396 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2397 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2398 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2399 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
2400 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
2401 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2402 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2403 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2404 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2405 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2406 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2407 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
2408 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
2409 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2410 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2411 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2412 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2414 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2415 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2416 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2417 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2418 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2419 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2420 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2421 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2422 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2423 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2424 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2425 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2426 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2427 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2428 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2429 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2430 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2431 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2432 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2433 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2434 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2436 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2437 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2438 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2439 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2440 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2441 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2442 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2443 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2444 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2445 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2446 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2447 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2448 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2449 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2450 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2451 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2452 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2454 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2455 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2457 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2458 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2459 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2460 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2462 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2463 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2464 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2465 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2466 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2467 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2468 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2469 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2470 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2471 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2472 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2473 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2474 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2476 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2477 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2479 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2480 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2481 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2482 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2483 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2484 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2485 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2486 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2488 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2489 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2490 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2491 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2492 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2493 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2494 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2495 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2496 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2497 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2498 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2499 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2500 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2501 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2502 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2503 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2504 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2506 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2507 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2508 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2509 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2511 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2512 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2513 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2514 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2516 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2517 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2518 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2519 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2520 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2522 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2523 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2524 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2525 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2527 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2528 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2529 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2530 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2531 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2532 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2533 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2534 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2536 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2537 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2539 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2540 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2541 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2542 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2543 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2544 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2545 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2546 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2548 case WINED3DTOP_MULTIPLYADD:
2549 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2550 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2551 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2552 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2553 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2554 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2555 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2556 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2557 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2558 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2559 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2560 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2561 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2562 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2563 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2564 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2565 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2566 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2567 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2568 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2571 case WINED3DTOP_BUMPENVMAP:
2575 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2576 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2582 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2583 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2587 } /* GL_NV_texture_env_combine4 */
2589 Handled = TRUE; /* Again, assume handled */
2591 case WINED3DTOP_DISABLE: /* Only for alpha */
2592 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2593 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2594 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2595 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2596 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2597 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2598 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2599 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2601 case WINED3DTOP_SELECTARG1:
2602 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2603 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2604 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2605 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2606 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2607 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2608 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2609 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2611 case WINED3DTOP_SELECTARG2:
2612 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2613 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2614 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2615 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2616 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2617 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2618 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2619 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2621 case WINED3DTOP_MODULATE:
2622 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2623 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2624 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2625 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2626 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2627 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2628 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2629 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2630 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2631 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2632 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2633 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2635 case WINED3DTOP_MODULATE2X:
2636 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2637 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2638 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2639 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2640 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2641 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2642 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2643 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2644 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2645 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2646 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2647 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2649 case WINED3DTOP_MODULATE4X:
2650 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2651 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2652 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2653 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2654 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2655 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2656 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2657 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2658 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2659 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2660 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2661 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2663 case WINED3DTOP_ADD:
2664 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2665 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2666 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2667 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2668 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2669 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2670 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2671 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2672 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2673 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2674 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2675 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2677 case WINED3DTOP_ADDSIGNED:
2678 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2679 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2680 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2681 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2682 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2683 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2684 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2685 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2686 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2687 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2688 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2689 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2691 case WINED3DTOP_ADDSIGNED2X:
2692 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2693 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2694 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2695 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2696 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2697 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2698 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2699 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2700 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2701 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2702 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2703 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2705 case WINED3DTOP_SUBTRACT:
2706 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2708 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2709 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2710 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2711 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2712 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2713 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2714 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2715 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2716 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2717 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2718 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2719 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2721 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2725 case WINED3DTOP_BLENDDIFFUSEALPHA:
2726 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2727 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2728 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2729 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2730 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2731 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2732 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2733 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2734 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2735 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2736 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2737 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2738 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2739 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2740 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2741 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2743 case WINED3DTOP_BLENDTEXTUREALPHA:
2744 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2745 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2746 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2747 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2748 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2749 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2750 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2751 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2752 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2753 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2754 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2755 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2756 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2757 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2758 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2759 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2761 case WINED3DTOP_BLENDFACTORALPHA:
2762 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2763 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2764 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2765 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2766 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2767 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2768 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2769 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2770 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2771 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2772 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2773 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2774 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2775 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2776 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2777 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2779 case WINED3DTOP_BLENDCURRENTALPHA:
2780 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2781 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2782 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2783 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2784 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2785 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2786 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2787 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2788 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2789 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2790 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2791 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2792 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2793 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2794 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2795 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2797 case WINED3DTOP_DOTPRODUCT3:
2798 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2800 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2801 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2803 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2805 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2806 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2808 FIXME("This version of opengl does not support GL_DOT3\n");
2810 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2811 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2812 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2813 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2814 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2815 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2816 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2817 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2818 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2819 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2821 case WINED3DTOP_LERP:
2822 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2823 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2824 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2825 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2826 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2827 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2828 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2829 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2830 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2831 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2832 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2833 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2834 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2835 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2836 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2837 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2839 case WINED3DTOP_ADDSMOOTH:
2840 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2842 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2843 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2844 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2845 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2847 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2848 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2849 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2850 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2852 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2853 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2854 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2855 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2856 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2857 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2858 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2859 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2860 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2861 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2862 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2863 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2867 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2868 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2870 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2871 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2872 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2873 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2874 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2875 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2876 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2877 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2878 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2879 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2880 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2881 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2882 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2883 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2884 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2885 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2889 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2890 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2892 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2893 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2894 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2895 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2897 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2898 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2899 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2900 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2902 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2903 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2904 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2905 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2906 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2907 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2908 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2909 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2910 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2911 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2912 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2913 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2917 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2918 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2920 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2921 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2922 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2923 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2924 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2925 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2926 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2927 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2929 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2930 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2931 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2932 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2934 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2935 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2936 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2937 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2938 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2939 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2940 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2941 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2945 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2946 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2948 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2949 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2950 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2951 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2953 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2954 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2955 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2956 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2958 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2959 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2960 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2961 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2962 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2963 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2964 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2965 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2966 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2967 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2968 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2969 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2973 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2974 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2976 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2977 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2978 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2979 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2981 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2982 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2983 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2984 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2986 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2987 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2988 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2989 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2991 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2992 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2993 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2994 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2996 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2997 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2998 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2999 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3000 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3001 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3002 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3003 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3007 case WINED3DTOP_MULTIPLYADD:
3008 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3010 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3011 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3012 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3013 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3014 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3015 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3016 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3017 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3018 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3019 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3020 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3021 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3022 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3023 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3024 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3025 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3029 case WINED3DTOP_BUMPENVMAPLUMINANCE:
3030 case WINED3DTOP_BUMPENVMAP:
3031 if (gl_info->supported[NV_TEXTURE_SHADER2])
3033 /* Technically texture shader support without register combiners is possible, but not expected to occur
3034 * on real world cards, so for now a fixme should be enough
3036 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3043 BOOL combineOK = TRUE;
3044 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3049 op2 = state->texture_states[Stage][WINED3DTSS_COLOROP];
3051 op2 = state->texture_states[Stage][WINED3DTSS_ALPHAOP];
3053 /* Note: If COMBINE4 in effect can't go back to combine! */
3055 case WINED3DTOP_ADDSMOOTH:
3056 case WINED3DTOP_BLENDTEXTUREALPHAPM:
3057 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
3058 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
3059 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
3060 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
3061 case WINED3DTOP_MULTIPLYADD:
3062 /* Ignore those implemented in both cases */
3064 case WINED3DTOP_SELECTARG1:
3065 case WINED3DTOP_SELECTARG2:
3070 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3077 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
3078 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
3084 /* After all the extensions, if still unhandled, report fixme */
3085 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3089 static void tex_colorop(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3091 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3092 BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage);
3093 DWORD mapped_stage = stateblock->device->texUnitMap[stage];
3094 const struct wined3d_gl_info *gl_info = context->gl_info;
3095 const struct wined3d_state *state = &stateblock->state;
3097 TRACE("Setting color op for stage %d\n", stage);
3099 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3100 if (use_ps(state)) return;
3102 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3104 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3106 if (tex_used && mapped_stage >= gl_info->limits.textures)
3108 FIXME("Attempt to enable unsupported stage!\n");
3111 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3112 checkGLcall("glActiveTextureARB");
3115 if (stage >= state->lowest_disabled_stage)
3117 TRACE("Stage disabled\n");
3118 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3120 /* Disable everything here */
3121 glDisable(GL_TEXTURE_2D);
3122 checkGLcall("glDisable(GL_TEXTURE_2D)");
3123 glDisable(GL_TEXTURE_3D);
3124 checkGLcall("glDisable(GL_TEXTURE_3D)");
3125 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3127 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3128 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3130 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3132 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3133 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3140 /* The sampler will also activate the correct texture dimensions, so no
3141 * need to do it here if the sampler for this stage is dirty. */
3142 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3143 texture_activate_dimensions(state->textures[stage], gl_info);
3145 set_tex_op(gl_info, state, FALSE, stage,
3146 state->texture_states[stage][WINED3DTSS_COLOROP],
3147 state->texture_states[stage][WINED3DTSS_COLORARG1],
3148 state->texture_states[stage][WINED3DTSS_COLORARG2],
3149 state->texture_states[stage][WINED3DTSS_COLORARG0]);
3152 void tex_alphaop(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3154 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3155 BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage);
3156 DWORD mapped_stage = stateblock->device->texUnitMap[stage];
3157 const struct wined3d_gl_info *gl_info = context->gl_info;
3158 DWORD op, arg1, arg2, arg0;
3160 TRACE("Setting alpha op for stage %d\n", stage);
3161 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3162 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3164 if (tex_used && mapped_stage >= gl_info->limits.textures)
3166 FIXME("Attempt to enable unsupported stage!\n");
3169 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3170 checkGLcall("glActiveTextureARB");
3173 op = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAOP];
3174 arg1 = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAARG1];
3175 arg2 = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAARG2];
3176 arg0 = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAARG0];
3178 if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && !stage && stateblock->state.textures[0])
3180 struct wined3d_texture *texture = stateblock->state.textures[0];
3181 GLenum texture_dimensions = texture->target;
3183 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3185 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3187 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3189 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3190 * properly. On the other hand applications can still use texture combiners apparently. This code
3191 * takes care that apps cannot remove the texture's alpha channel entirely.
3193 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3194 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3195 * and alpha component of diffuse color to draw things like translucent text and perform other
3198 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3199 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3200 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3201 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3202 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3203 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3204 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3205 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3206 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3209 * What to do with multitexturing? So far no app has been found that uses color keying with
3211 if (op == WINED3DTOP_DISABLE)
3213 arg1 = WINED3DTA_TEXTURE;
3214 op = WINED3DTOP_SELECTARG1;
3216 else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE)
3218 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
3220 arg2 = WINED3DTA_TEXTURE;
3221 op = WINED3DTOP_MODULATE;
3223 else arg1 = WINED3DTA_TEXTURE;
3225 else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE)
3227 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
3229 arg1 = WINED3DTA_TEXTURE;
3230 op = WINED3DTOP_MODULATE;
3232 else arg2 = WINED3DTA_TEXTURE;
3238 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3239 * this if block here, and the other code(color keying, texture unit selection) are the same
3241 TRACE("Setting alpha op for stage %d\n", stage);
3242 if (gl_info->supported[NV_REGISTER_COMBINERS])
3244 set_tex_op_nvrc(gl_info, &stateblock->state, TRUE, stage, op, arg1, arg2, arg0,
3245 mapped_stage, stateblock->state.texture_states[stage][WINED3DTSS_RESULTARG]);
3249 set_tex_op(gl_info, &stateblock->state, TRUE, stage, op, arg1, arg2, arg0);
3253 static void transform_texture(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3255 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3256 DWORD mapped_stage = stateblock->device->texUnitMap[texUnit];
3257 const struct wined3d_gl_info *gl_info = context->gl_info;
3258 const struct wined3d_state *state = &stateblock->state;
3262 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3263 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3265 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3269 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3270 if (mapped_stage >= gl_info->limits.textures) return;
3272 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3273 checkGLcall("glActiveTextureARB");
3274 generated = (state->texture_states[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3275 coordIdx = min(state->texture_states[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000ffff], MAX_TEXTURES - 1);
3277 set_texture_matrix(&state->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
3278 state->texture_states[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
3279 generated, context->last_was_rhw,
3280 stateblock->device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3281 ? stateblock->device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3282 : WINED3DFMT_UNKNOWN,
3283 stateblock->device->frag_pipe->ffp_proj_control);
3285 /* The sampler applying function calls us if this changes */
3286 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3289 FIXME("Non-power2 texture being used with generated texture coords\n");
3291 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3292 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3295 TRACE("Non power two matrix multiply fixup\n");
3296 glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3301 static void unloadTexCoords(const struct wined3d_gl_info *gl_info)
3303 unsigned int texture_idx;
3305 for (texture_idx = 0; texture_idx < gl_info->limits.texture_stages; ++texture_idx)
3307 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3308 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3312 static void loadTexCoords(const struct wined3d_gl_info *gl_info, struct wined3d_stateblock *stateblock,
3313 const struct wined3d_stream_info *si, GLuint *curVBO)
3315 unsigned int mapped_stage = 0;
3316 unsigned int textureNo = 0;
3318 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3320 int coordIdx = stateblock->state.texture_states[textureNo][WINED3DTSS_TEXCOORDINDEX];
3322 mapped_stage = stateblock->device->texUnitMap[textureNo];
3323 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3325 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3327 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3328 const struct wined3d_stream_state *stream = &stateblock->state.streams[e->stream_idx];
3330 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
3331 textureNo, mapped_stage, coordIdx, e->data);
3333 if (*curVBO != e->buffer_object)
3335 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
3336 checkGLcall("glBindBufferARB");
3337 *curVBO = e->buffer_object;
3340 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3341 checkGLcall("glClientActiveTextureARB");
3343 /* The coords to supply depend completely on the fvf / vertex shader */
3344 glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3345 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
3346 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3348 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3351 if (gl_info->supported[NV_REGISTER_COMBINERS])
3353 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3354 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3356 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3360 checkGLcall("loadTexCoords");
3363 static void tex_coordindex(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3365 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3366 DWORD mapped_stage = stateblock->device->texUnitMap[stage];
3367 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3368 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3369 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3370 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3371 const struct wined3d_gl_info *gl_info = context->gl_info;
3373 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3375 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3379 if (mapped_stage >= gl_info->limits.fragment_samplers)
3381 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3384 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3385 checkGLcall("glActiveTextureARB");
3387 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3389 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3390 * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
3391 * means use the vertex position (camera-space) as the input texture coordinates
3392 * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
3393 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3394 * to the TEXCOORDINDEX value
3396 switch (stateblock->state.texture_states[stage][WINED3DTSS_TEXCOORDINDEX] & 0xffff0000)
3398 case WINED3DTSS_TCI_PASSTHRU:
3399 /* Use the specified texture coordinates contained within the
3400 * vertex format. This value resolves to zero. */
3401 glDisable(GL_TEXTURE_GEN_S);
3402 glDisable(GL_TEXTURE_GEN_T);
3403 glDisable(GL_TEXTURE_GEN_R);
3404 glDisable(GL_TEXTURE_GEN_Q);
3405 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3408 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3409 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3410 * as the input texture coordinates for this stage's texture transformation. This
3411 * equates roughly to EYE_LINEAR */
3413 glMatrixMode(GL_MODELVIEW);
3416 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3417 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3418 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3419 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3421 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3423 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3424 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3425 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3426 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3428 glEnable(GL_TEXTURE_GEN_S);
3429 glEnable(GL_TEXTURE_GEN_T);
3430 glEnable(GL_TEXTURE_GEN_R);
3431 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3435 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3436 /* Note that NV_TEXGEN_REFLECTION support is implied when
3437 * ARB_TEXTURE_CUBE_MAP is supported */
3438 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3440 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3444 glMatrixMode(GL_MODELVIEW);
3447 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3448 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3449 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3450 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3452 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3454 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3455 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3456 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3457 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3459 glEnable(GL_TEXTURE_GEN_S);
3460 glEnable(GL_TEXTURE_GEN_T);
3461 glEnable(GL_TEXTURE_GEN_R);
3462 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3466 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3467 /* Note that NV_TEXGEN_REFLECTION support is implied when
3468 * ARB_TEXTURE_CUBE_MAP is supported */
3469 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3471 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3475 glMatrixMode(GL_MODELVIEW);
3478 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3479 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3480 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3481 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3483 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3485 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3486 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3487 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3488 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3490 glEnable(GL_TEXTURE_GEN_S);
3491 glEnable(GL_TEXTURE_GEN_T);
3492 glEnable(GL_TEXTURE_GEN_R);
3493 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3497 case WINED3DTSS_TCI_SPHEREMAP:
3498 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3499 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3500 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3502 glEnable(GL_TEXTURE_GEN_S);
3503 glEnable(GL_TEXTURE_GEN_T);
3504 glDisable(GL_TEXTURE_GEN_R);
3505 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3510 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %#x.\n",
3511 stateblock->state.texture_states[stage][WINED3DTSS_TEXCOORDINDEX]);
3512 glDisable(GL_TEXTURE_GEN_S);
3513 glDisable(GL_TEXTURE_GEN_T);
3514 glDisable(GL_TEXTURE_GEN_R);
3515 glDisable(GL_TEXTURE_GEN_Q);
3516 checkGLcall("Disable texgen.");
3521 /* Update the texture matrix */
3522 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
3523 transform_texture(STATE_TEXTURESTAGE(stage, WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
3526 if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
3527 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3528 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3529 * and do all the things linked to it
3530 * TODO: Tidy that up to reload only the arrays of the changed unit
3532 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3534 unloadTexCoords(gl_info);
3535 loadTexCoords(gl_info, stateblock, &stateblock->device->strided_streams, &curVBO);
3539 static void shaderconstant(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3541 const struct wined3d_state *state = &stateblock->state;
3542 IWineD3DDeviceImpl *device = stateblock->device;
3544 /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
3545 * has an update pending
3547 if(isStateDirty(context, STATE_VDECL) ||
3548 isStateDirty(context, STATE_PIXELSHADER)) {
3552 device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
3555 static void tex_bumpenvlscale(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3557 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3558 const struct wined3d_shader *ps = stateblock->state.pixel_shader;
3560 if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3562 /* The pixel shader has to know the luminance scale. Do a constants update if it
3563 * isn't scheduled anyway
3565 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3566 !isStateDirty(context, STATE_PIXELSHADER)) {
3567 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3572 static void sampler_texmatrix(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3574 const DWORD sampler = state - STATE_SAMPLER(0);
3575 struct wined3d_texture *texture = stateblock->state.textures[sampler];
3577 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
3579 if(!texture) return;
3580 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3581 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3582 * scaling is reapplied or removed, the texture matrix has to be reapplied
3584 * The mapped stage is already active because the sampler() function below, which is part of the
3587 if (sampler < MAX_TEXTURES)
3589 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3591 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3593 if (texIsPow2) context->lastWasPow2Texture |= 1 << sampler;
3594 else context->lastWasPow2Texture &= ~(1 << sampler);
3595 transform_texture(STATE_TEXTURESTAGE(stateblock->device->texUnitMap[sampler],
3596 WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
3601 static void sampler(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3603 DWORD sampler = state_id - STATE_SAMPLER(0);
3604 IWineD3DDeviceImpl *device = stateblock->device;
3605 DWORD mapped_stage = device->texUnitMap[sampler];
3606 const struct wined3d_gl_info *gl_info = context->gl_info;
3607 const struct wined3d_state *state = &stateblock->state;
3613 TRACE("Sampler: %d\n", sampler);
3614 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3615 * only has to bind textures and set the per texture states
3618 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3620 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3624 if (mapped_stage >= gl_info->limits.combined_samplers)
3628 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3629 checkGLcall("glActiveTextureARB");
3631 if (state->textures[sampler])
3633 struct wined3d_texture *texture = state->textures[sampler];
3634 BOOL srgb = state->sampler_states[sampler][WINED3DSAMP_SRGBTEXTURE];
3636 texture->texture_ops->texture_bind(texture, gl_info, srgb);
3637 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3639 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3641 tmpvalue.d = state->sampler_states[sampler][WINED3DSAMP_MIPMAPLODBIAS];
3642 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3643 GL_TEXTURE_LOD_BIAS_EXT,
3645 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3648 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3650 if (state->render_states[WINED3DRS_COLORKEYENABLE] && !sampler)
3652 /* If color keying is enabled update the alpha test, it depends on the existence
3653 * of a color key in stage 0
3655 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3659 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3660 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3661 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3663 else if (mapped_stage < gl_info->limits.textures)
3665 if (sampler < state->lowest_disabled_stage)
3667 /* TODO: What should I do with pixel shaders here ??? */
3668 if (state->render_states[WINED3DRS_COLORKEYENABLE] && !sampler)
3670 /* If color keying is enabled update the alpha test, it depends on the existence
3671 * of a color key in stage 0
3673 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3675 } /* Otherwise tex_colorop disables the stage */
3676 glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[sampler]);
3677 checkGLcall("glBindTexture(GL_TEXTURE_2D, device->dummyTextureName[sampler])");
3681 void apply_pixelshader(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3683 const struct wined3d_state *state = &stateblock->state;
3684 IWineD3DDeviceImpl *device = stateblock->device;
3685 BOOL use_vshader = use_vs(state);
3686 BOOL use_pshader = use_ps(state);
3690 if(!context->last_was_pshader) {
3691 /* Former draw without a pixel shader, some samplers
3692 * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
3693 * make sure to enable them
3695 for(i=0; i < MAX_FRAGMENT_SAMPLERS; i++) {
3696 if(!isStateDirty(context, STATE_SAMPLER(i))) {
3697 sampler(STATE_SAMPLER(i), stateblock, context);
3700 context->last_was_pshader = TRUE;
3702 /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
3703 * if a different texture was bound. I don't have to do anything.
3707 /* Disabled the pixel shader - color ops weren't applied
3708 * while it was enabled, so re-apply them. */
3709 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3711 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)))
3712 stateblock_apply_state(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
3714 context->last_was_pshader = FALSE;
3717 if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
3718 device->shader_backend->shader_select(context, use_pshader, use_vshader);
3720 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
3721 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
3726 static void shader_bumpenvmat(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3728 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3729 const struct wined3d_shader *ps = stateblock->state.pixel_shader;
3731 if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3733 /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
3736 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3737 !isStateDirty(context, STATE_PIXELSHADER)) {
3738 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3743 static void transform_world(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3745 /* This function is called by transform_view below if the view matrix was changed too
3747 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3748 * does not always update the world matrix, only on a switch between transformed
3749 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3750 * draw, but that should be rather rare and cheaper in total.
3752 glMatrixMode(GL_MODELVIEW);
3753 checkGLcall("glMatrixMode");
3755 if(context->last_was_rhw) {
3757 checkGLcall("glLoadIdentity()");
3759 /* In the general case, the view matrix is the identity matrix */
3760 if (stateblock->device->view_ident)
3762 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3763 checkGLcall("glLoadMatrixf");
3767 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
3768 checkGLcall("glLoadMatrixf");
3769 glMultMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3770 checkGLcall("glMultMatrixf");
3775 static void clipplane(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3777 const struct wined3d_state *state = &stateblock->state;
3778 UINT index = state_id - STATE_CLIPPLANE(0);
3780 if (isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= context->gl_info->limits.clipplanes)
3785 glMatrixMode(GL_MODELVIEW);
3788 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3790 glLoadMatrixf(&state->transforms[WINED3DTS_VIEW].u.m[0][0]);
3792 /* with vertex shaders, clip planes are not transformed in direct3d,
3793 * in OpenGL they are still transformed by the model view.
3797 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3798 state->clip_planes[index][0],
3799 state->clip_planes[index][1],
3800 state->clip_planes[index][2],
3801 state->clip_planes[index][3]);
3802 glClipPlane(GL_CLIP_PLANE0 + index, state->clip_planes[index]);
3803 checkGLcall("glClipPlane");
3808 static void transform_worldex(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3810 UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
3812 TRACE("Setting world matrix %d\n", matrix);
3814 if (matrix >= context->gl_info->limits.blends)
3816 WARN("Unsupported blend matrix set\n");
3818 } else if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
3822 /* GL_MODELVIEW0_ARB: 0x1700
3823 * GL_MODELVIEW1_ARB: 0x850a
3824 * GL_MODELVIEW2_ARB: 0x8722
3825 * GL_MODELVIEW3_ARB: 0x8723
3827 * GL_MODELVIEW31_ARB: 0x873F
3829 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3830 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3832 glMatrixMode(glMat);
3833 checkGLcall("glMatrixMode(glMat)");
3835 /* World matrix 0 is multiplied with the view matrix because d3d uses 3 matrices while gl uses only 2. To avoid
3836 * weighting the view matrix incorrectly it has to be multiplied into every gl modelview matrix
3838 if (stateblock->device->view_ident)
3840 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3841 checkGLcall("glLoadMatrixf");
3845 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
3846 checkGLcall("glLoadMatrixf");
3847 glMultMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3848 checkGLcall("glMultMatrixf");
3852 static void state_vertexblend_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3854 WINED3DVERTEXBLENDFLAGS f = stateblock->state.render_states[WINED3DRS_VERTEXBLEND];
3855 static unsigned int once;
3857 if (f == WINED3DVBF_DISABLE) return;
3859 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3860 else WARN("Vertex blend flags %#x not supported.\n", f);
3863 static void state_vertexblend(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3865 WINED3DVERTEXBLENDFLAGS val = stateblock->state.render_states[WINED3DRS_VERTEXBLEND];
3866 const struct wined3d_gl_info *gl_info = context->gl_info;
3867 static unsigned int once;
3870 case WINED3DVBF_1WEIGHTS:
3871 case WINED3DVBF_2WEIGHTS:
3872 case WINED3DVBF_3WEIGHTS:
3873 glEnable(GL_VERTEX_BLEND_ARB);
3874 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3876 /* D3D adds one more matrix which has weight (1 - sum(weights)). This is enabled at context
3877 * creation with enabling GL_WEIGHT_SUM_UNITY_ARB.
3879 GL_EXTCALL(glVertexBlendARB(stateblock->state.render_states[WINED3DRS_VERTEXBLEND] + 1));
3881 if (!stateblock->device->vertexBlendUsed)
3884 for (i = 1; i < gl_info->limits.blends; ++i)
3886 if (!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i))))
3888 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)), stateblock, context);
3891 stateblock->device->vertexBlendUsed = TRUE;
3895 case WINED3DVBF_TWEENING:
3896 case WINED3DVBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3897 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3898 else WARN("Vertex blend flags %#x not supported.\n", val);
3900 case WINED3DVBF_DISABLE:
3901 glDisable(GL_VERTEX_BLEND_ARB);
3902 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3907 static void transform_view(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3909 const struct wined3d_gl_info *gl_info = context->gl_info;
3910 const struct wined3d_light_info *light = NULL;
3913 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3914 * NOTE: We have to reset the positions even if the light/plane is not currently
3915 * enabled, since the call to enable it will not reset the position.
3916 * NOTE2: Apparently texture transforms do NOT need reapplying
3919 glMatrixMode(GL_MODELVIEW);
3920 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3921 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
3922 checkGLcall("glLoadMatrixf(...)");
3924 /* Reset lights. TODO: Call light apply func */
3925 for (k = 0; k < stateblock->device->maxConcurrentLights; ++k)
3927 light = stateblock->state.lights[k];
3928 if(!light) continue;
3929 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3930 checkGLcall("glLightfv posn");
3931 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3932 checkGLcall("glLightfv dirn");
3935 /* Reset Clipping Planes */
3936 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3938 if(!isStateDirty(context, STATE_CLIPPLANE(k))) {
3939 clipplane(STATE_CLIPPLANE(k), stateblock, context);
3943 if(context->last_was_rhw) {
3945 checkGLcall("glLoadIdentity()");
3946 /* No need to update the world matrix, the identity is fine */
3950 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3951 * No need to do it here if the state is scheduled for update.
3953 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
3954 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
3957 /* Avoid looping over a number of matrices if the app never used the functionality */
3958 if (stateblock->device->vertexBlendUsed)
3960 for (k = 1; k < gl_info->limits.blends; ++k)
3962 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)))) {
3963 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)), stateblock, context);
3969 static void transform_projection(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
3971 glMatrixMode(GL_PROJECTION);
3972 checkGLcall("glMatrixMode(GL_PROJECTION)");
3974 checkGLcall("glLoadIdentity");
3976 if (context->last_was_rhw)
3978 double x = stateblock->state.viewport.X;
3979 double y = stateblock->state.viewport.Y;
3980 double w = stateblock->state.viewport.Width;
3981 double h = stateblock->state.viewport.Height;
3983 TRACE("Calling glOrtho with x %.8e, y %.8e, w %.8e, h %.8e.\n", x, y, w, h);
3984 if (context->render_offscreen)
3985 glOrtho(x, x + w, -y, -y - h, 0.0, -1.0);
3987 glOrtho(x, x + w, y + h, y, 0.0, -1.0);
3988 checkGLcall("glOrtho");
3990 /* D3D texture coordinates are flipped compared to OpenGL ones, so
3991 * render everything upside down when rendering offscreen. */
3992 if (context->render_offscreen)
3994 glScalef(1.0f, -1.0f, 1.0f);
3995 checkGLcall("glScalef");
3998 /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
3999 glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f);
4000 checkGLcall("glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f)");
4004 /* The rule is that the window coordinate 0 does not correspond to the
4005 beginning of the first pixel, but the center of the first pixel.
4006 As a consequence if you want to correctly draw one line exactly from
4007 the left to the right end of the viewport (with all matrices set to
4008 be identity), the x coords of both ends of the line would be not
4009 -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
4012 1.0 / Width is used because the coord range goes from -1.0 to 1.0, then we
4013 divide by the Width/Height, so we need the half range(1.0) to translate by
4016 The other fun is that d3d's output z range after the transformation is [0;1],
4017 but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl
4018 scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot
4019 of Z buffer precision and the clear values do not match in the z test. Thus scale
4020 [0;1] to [-1;1], so when gl undoes that we utilize the full z range
4024 * Careful with the order of operations here, we're essentially working backwards:
4026 * y = (y - 1/h) * flip;
4030 * glTranslatef(0.0, 0.0, -1.0);
4031 * glScalef(1.0, 1.0, 2.0);
4033 * glScalef(1.0, flip, 1.0);
4034 * glTranslatef(1/w, -1/h, 0.0);
4036 * This is equivalent to:
4037 * glTranslatef(1/w, -flip/h, -1.0)
4038 * glScalef(1.0, flip, 2.0);
4041 /* Translate by slightly less than a half pixel to force a top-left
4042 * filling convention. We want the difference to be large enough that
4043 * it doesn't get lost due to rounding inside the driver, but small
4044 * enough to prevent it from interfering with any anti-aliasing. */
4045 GLfloat xoffset = (63.0f / 64.0f) / stateblock->state.viewport.Width;
4046 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->state.viewport.Height;
4048 if (context->render_offscreen)
4050 /* D3D texture coordinates are flipped compared to OpenGL ones, so
4051 * render everything upside down when rendering offscreen. */
4052 glTranslatef(xoffset, -yoffset, -1.0f);
4053 checkGLcall("glTranslatef(xoffset, -yoffset, -1.0f)");
4054 glScalef(1.0f, -1.0f, 2.0f);
4056 glTranslatef(xoffset, yoffset, -1.0f);
4057 checkGLcall("glTranslatef(xoffset, yoffset, -1.0f)");
4058 glScalef(1.0f, 1.0f, 2.0f);
4060 checkGLcall("glScalef");
4062 glMultMatrixf(&stateblock->state.transforms[WINED3DTS_PROJECTION].u.m[0][0]);
4063 checkGLcall("glLoadMatrixf");
4067 /* This should match any arrays loaded in loadVertexData.
4068 * TODO: Only load / unload arrays if we have to.
4070 static inline void unloadVertexData(const struct wined3d_gl_info *gl_info)
4072 glDisableClientState(GL_VERTEX_ARRAY);
4073 glDisableClientState(GL_NORMAL_ARRAY);
4074 glDisableClientState(GL_COLOR_ARRAY);
4075 if (gl_info->supported[EXT_SECONDARY_COLOR])
4077 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4079 if (gl_info->supported[ARB_VERTEX_BLEND])
4081 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4083 unloadTexCoords(gl_info);
4086 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4088 const struct wined3d_gl_info *gl_info = context->gl_info;
4090 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4091 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4093 context->numbered_array_mask &= ~(1 << i);
4096 /* This should match any arrays loaded in loadNumberedArrays
4097 * TODO: Only load / unload arrays if we have to.
4099 static inline void unloadNumberedArrays(struct wined3d_context *context)
4101 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4102 GLint maxAttribs = 16;
4105 /* Leave all the attribs disabled */
4106 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
4107 /* MESA does not support it right not */
4108 if (glGetError() != GL_NO_ERROR)
4110 for (i = 0; i < maxAttribs; ++i) {
4111 unload_numbered_array(context, i);
4115 static void loadNumberedArrays(struct wined3d_stateblock *stateblock,
4116 const struct wined3d_stream_info *stream_info, struct wined3d_context *context)
4118 const struct wined3d_gl_info *gl_info = context->gl_info;
4119 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4121 struct wined3d_buffer *vb;
4123 /* Default to no instancing */
4124 stateblock->device->instancedDraw = FALSE;
4126 for (i = 0; i < MAX_ATTRIBS; i++)
4128 const struct wined3d_stream_state *stream;
4130 if (!(stream_info->use_map & (1 << i)))
4132 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4136 stream = &stateblock->state.streams[stream_info->elements[i].stream_idx];
4138 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4139 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4141 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4142 stateblock->device->instancedDraw = TRUE;
4146 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].buffer_object);
4148 if (stream_info->elements[i].stride)
4150 if (curVBO != stream_info->elements[i].buffer_object)
4152 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].buffer_object));
4153 checkGLcall("glBindBufferARB");
4154 curVBO = stream_info->elements[i].buffer_object;
4156 /* Use the VBO to find out if a vertex buffer exists, not the vb
4157 * pointer. vb can point to a user pointer data blob. In that case
4158 * curVBO will be 0. If there is a vertex buffer but no vbo we
4159 * won't be load converted attributes anyway. */
4160 vb = stream->buffer;
4161 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4162 stream_info->elements[i].format->gl_vtx_type,
4163 stream_info->elements[i].format->gl_normalized,
4164 stream_info->elements[i].stride, stream_info->elements[i].data
4165 + stateblock->state.load_base_vertex_index * stream_info->elements[i].stride
4168 if (!(context->numbered_array_mask & (1 << i)))
4170 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4171 context->numbered_array_mask |= (1 << i);
4176 /* Stride = 0 means always the same values.
4177 * glVertexAttribPointerARB doesn't do that. Instead disable the
4178 * pointer and set up the attribute statically. But we have to
4179 * figure out the system memory address. */
4180 const BYTE *ptr = stream_info->elements[i].data + stream->offset;
4181 if (stream_info->elements[i].buffer_object)
4183 vb = stream->buffer;
4184 ptr += (ULONG_PTR)buffer_get_sysmem(vb, gl_info);
4187 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4189 switch (stream_info->elements[i].format->id)
4191 case WINED3DFMT_R32_FLOAT:
4192 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4194 case WINED3DFMT_R32G32_FLOAT:
4195 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4197 case WINED3DFMT_R32G32B32_FLOAT:
4198 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4200 case WINED3DFMT_R32G32B32A32_FLOAT:
4201 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4204 case WINED3DFMT_R8G8B8A8_UINT:
4205 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4207 case WINED3DFMT_B8G8R8A8_UNORM:
4208 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4210 const DWORD *src = (const DWORD *)ptr;
4211 DWORD c = *src & 0xff00ff00;
4212 c |= (*src & 0xff0000) >> 16;
4213 c |= (*src & 0xff) << 16;
4214 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4217 /* else fallthrough */
4218 case WINED3DFMT_R8G8B8A8_UNORM:
4219 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4222 case WINED3DFMT_R16G16_SINT:
4223 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4225 case WINED3DFMT_R16G16B16A16_SINT:
4226 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4229 case WINED3DFMT_R16G16_SNORM:
4231 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4232 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4235 case WINED3DFMT_R16G16_UNORM:
4237 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4238 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4241 case WINED3DFMT_R16G16B16A16_SNORM:
4242 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4244 case WINED3DFMT_R16G16B16A16_UNORM:
4245 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4248 case WINED3DFMT_R10G10B10A2_UINT:
4249 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4250 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4252 case WINED3DFMT_R10G10B10A2_SNORM:
4253 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4254 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4257 case WINED3DFMT_R16G16_FLOAT:
4258 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4259 * byte float according to the IEEE standard
4261 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4263 case WINED3DFMT_R16G16B16A16_FLOAT:
4264 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4268 ERR("Unexpected declaration in stride 0 attributes\n");
4274 checkGLcall("Loading numbered arrays");
4277 /* Used from 2 different functions, and too big to justify making it inlined */
4278 static void loadVertexData(const struct wined3d_context *context, struct wined3d_stateblock *stateblock,
4279 const struct wined3d_stream_info *si)
4281 const struct wined3d_gl_info *gl_info = context->gl_info;
4282 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4283 const struct wined3d_stream_info_element *e;
4284 const struct wined3d_stream_state *stream;
4286 TRACE("Using fast vertex array code\n");
4288 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4289 stateblock->device->instancedDraw = FALSE;
4291 /* Blend Data ---------------------------------------------- */
4292 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4293 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4295 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4296 stream = &stateblock->state.streams[e->stream_idx];
4298 if (gl_info->supported[ARB_VERTEX_BLEND])
4300 TRACE("Blend %u %p %u\n", e->format->component_count,
4301 e->data + stateblock->state.load_base_vertex_index * e->stride, e->stride + stream->offset);
4303 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4304 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4306 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4308 if (curVBO != e->buffer_object)
4310 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4311 checkGLcall("glBindBufferARB");
4312 curVBO = e->buffer_object;
4315 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4316 e->format->gl_vtx_format,
4317 e->format->gl_vtx_type,
4319 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4320 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4321 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset));
4323 checkGLcall("glWeightPointerARB");
4325 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4330 FIXME("blendMatrixIndices support\n");
4335 /* TODO: support blends in drawStridedSlow
4336 * No need to write a FIXME here, this is done after the general vertex decl decoding
4338 WARN("unsupported blending in openGl\n");
4343 if (gl_info->supported[ARB_VERTEX_BLEND])
4345 static const GLbyte one = 1;
4346 GL_EXTCALL(glWeightbvARB(1, &one));
4347 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4351 /* Point Size ----------------------------------------------*/
4352 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4354 /* no such functionality in the fixed function GL pipeline */
4355 TRACE("Cannot change ptSize here in openGl\n");
4356 /* TODO: Implement this function in using shaders if they are available */
4359 /* Vertex Pointers -----------------------------------------*/
4360 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4362 e = &si->elements[WINED3D_FFP_POSITION];
4363 stream = &stateblock->state.streams[e->stream_idx];
4365 if (curVBO != e->buffer_object)
4367 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4368 checkGLcall("glBindBufferARB");
4369 curVBO = e->buffer_object;
4372 /* min(WINED3D_ATR_FORMAT(position),3) to Disable RHW mode as 'w' coord
4373 handling for rhw mode should not impact screen position whereas in GL it does.
4374 This may result in very slightly distorted textures in rhw mode.
4375 There's always the other option of fixing the view matrix to
4376 prevent w from having any effect.
4378 This only applies to user pointer sources, in VBOs the vertices are fixed up
4380 if (!e->buffer_object)
4382 TRACE("glVertexPointer(3, %#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4383 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4384 glVertexPointer(3 /* min(e->format->gl_vtx_format, 3) */, e->format->gl_vtx_type, e->stride,
4385 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4389 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4390 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4391 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4392 glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4393 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4395 checkGLcall("glVertexPointer(...)");
4396 glEnableClientState(GL_VERTEX_ARRAY);
4397 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4400 /* Normals -------------------------------------------------*/
4401 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4403 e = &si->elements[WINED3D_FFP_NORMAL];
4404 stream = &stateblock->state.streams[e->stream_idx];
4406 if (curVBO != e->buffer_object)
4408 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4409 checkGLcall("glBindBufferARB");
4410 curVBO = e->buffer_object;
4413 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4414 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4415 glNormalPointer(e->format->gl_vtx_type, e->stride,
4416 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4417 checkGLcall("glNormalPointer(...)");
4418 glEnableClientState(GL_NORMAL_ARRAY);
4419 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4422 glNormal3f(0, 0, 0);
4423 checkGLcall("glNormal3f(0, 0, 0)");
4426 /* Diffuse Colour --------------------------------------------*/
4427 /* WARNING: Data here MUST be in RGBA format, so cannot */
4428 /* go directly into fast mode from app pgm, because */
4429 /* directx requires data in BGRA format. */
4430 /* currently fixupVertices swizzles the format, but this isn't*/
4431 /* very practical when using VBOs */
4432 /* NOTE: Unless we write a vertex shader to swizzle the colour*/
4433 /* , or the user doesn't care and wants the speed advantage */
4435 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4437 e = &si->elements[WINED3D_FFP_DIFFUSE];
4438 stream = &stateblock->state.streams[e->stream_idx];
4440 if (curVBO != e->buffer_object)
4442 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4443 checkGLcall("glBindBufferARB");
4444 curVBO = e->buffer_object;
4447 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4448 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4449 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4450 glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4451 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4452 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4453 glEnableClientState(GL_COLOR_ARRAY);
4454 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4457 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4458 checkGLcall("glColor4f(1, 1, 1, 1)");
4461 /* Specular Colour ------------------------------------------*/
4462 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4464 TRACE("setting specular colour\n");
4466 e = &si->elements[WINED3D_FFP_SPECULAR];
4467 stream = &stateblock->state.streams[e->stream_idx];
4469 if (gl_info->supported[EXT_SECONDARY_COLOR])
4471 GLenum type = e->format->gl_vtx_type;
4472 GLint format = e->format->gl_vtx_format;
4474 if (curVBO != e->buffer_object)
4476 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4477 checkGLcall("glBindBufferARB");
4478 curVBO = e->buffer_object;
4481 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4483 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4484 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4485 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4486 * 4 component secondary colors use it
4488 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4489 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4490 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4491 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset));
4492 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4498 case GL_UNSIGNED_BYTE:
4499 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4500 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4501 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4502 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset));
4503 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4507 FIXME("Add 4 component specular color pointers for type %x\n", type);
4508 /* Make sure that the right color component is dropped */
4509 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4510 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4511 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4512 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset));
4513 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4516 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4517 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4521 WARN("Specular colour is not supported in this GL implementation.\n");
4526 if (gl_info->supported[EXT_SECONDARY_COLOR])
4528 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4529 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4533 WARN("Specular colour is not supported in this GL implementation.\n");
4537 /* Texture coords -------------------------------------------*/
4538 loadTexCoords(gl_info, stateblock, si, &curVBO);
4541 static void streamsrc(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4543 IWineD3DDeviceImpl *device = stateblock->device;
4544 BOOL load_numbered = use_vs(&stateblock->state) && !device->useDrawStridedSlow;
4545 BOOL load_named = !use_vs(&stateblock->state) && !device->useDrawStridedSlow;
4547 if (context->numberedArraysLoaded && !load_numbered)
4549 unloadNumberedArrays(context);
4550 context->numberedArraysLoaded = FALSE;
4551 context->numbered_array_mask = 0;
4553 else if (context->namedArraysLoaded)
4555 unloadVertexData(context->gl_info);
4556 context->namedArraysLoaded = FALSE;
4561 TRACE("Loading numbered arrays\n");
4562 loadNumberedArrays(stateblock, &device->strided_streams, context);
4563 context->numberedArraysLoaded = TRUE;
4565 else if (load_named)
4567 TRACE("Loading vertex data\n");
4568 loadVertexData(context, stateblock, &device->strided_streams);
4569 context->namedArraysLoaded = TRUE;
4573 static void vertexdeclaration(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4575 const struct wined3d_gl_info *gl_info = context->gl_info;
4576 const struct wined3d_state *state = &stateblock->state;
4577 BOOL useVertexShaderFunction = use_vs(state);
4578 BOOL usePixelShaderFunction = use_ps(state);
4579 BOOL updateFog = FALSE;
4580 IWineD3DDeviceImpl *device = stateblock->device;
4582 BOOL wasrhw = context->last_was_rhw;
4585 transformed = device->strided_streams.position_transformed;
4586 if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
4591 context->last_was_rhw = TRUE;
4594 /* Untransformed, so relies on the view and projection matrices */
4595 context->last_was_rhw = FALSE;
4596 /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
4597 device->untransformed = TRUE;
4600 /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
4601 * off this function will be called again anyway to make sure they're properly set
4603 if(!useVertexShaderFunction) {
4604 /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
4605 * or transformed / untransformed was switched
4607 if(wasrhw != context->last_was_rhw &&
4608 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
4609 !isStateDirty(context, STATE_VIEWPORT)) {
4610 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4612 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4615 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4616 * this check will fail and the matrix not applied again. This is OK because a simple
4617 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4618 * needs of the vertex declaration.
4620 * World and view matrix go into the same gl matrix, so only apply them when neither is
4623 if(transformed != wasrhw &&
4624 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
4625 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
4626 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4629 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
4630 state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
4632 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
4633 state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
4636 if(context->last_was_vshader) {
4638 if(!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
4639 state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
4641 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4643 clipplane(STATE_CLIPPLANE(i), stateblock, context);
4646 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
4647 state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
4650 if(!context->last_was_vshader) {
4651 static BOOL warned = FALSE;
4652 if(!device->vs_clipping) {
4653 /* Disable all clip planes to get defined results on all drivers. See comment in the
4654 * state_clipping state handler
4656 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4658 glDisable(GL_CLIP_PLANE0 + i);
4659 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4662 if (!warned && stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
4664 FIXME("Clipping not supported with vertex shaders\n");
4669 /* Apply the transform matrices when switching from rhw drawing to vertex shaders. Vertex
4670 * shaders themselves do not need it, but the matrices are not reapplied automatically when
4671 * switching back from vertex shaders to fixed function processing. So make sure we leave the
4672 * fixed function vertex processing states back in a sane state before switching to shaders
4674 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4675 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4677 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
4678 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4683 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4684 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4685 * device->vs_clipping is false.
4687 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4689 clipplane(STATE_CLIPPLANE(i), stateblock, context);
4694 /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
4697 if (!isStateDirty(context, STATE_PIXELSHADER)) {
4698 device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4700 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
4701 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
4705 context->last_was_vshader = useVertexShaderFunction;
4707 if (updateFog) stateblock_apply_state(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context);
4709 if(!useVertexShaderFunction) {
4711 for(i = 0; i < MAX_TEXTURES; i++) {
4712 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i))) {
4713 transform_texture(STATE_TEXTURESTAGE(i, WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
4719 static void viewport_miscpart(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4721 struct wined3d_surface *target = stateblock->device->render_targets[0];
4723 WINED3DVIEWPORT vp = stateblock->state.viewport;
4725 if (vp.Width > target->resource.width)
4726 vp.Width = target->resource.width;
4727 if (vp.Height > target->resource.height)
4728 vp.Height = target->resource.height;
4730 glDepthRange(vp.MinZ, vp.MaxZ);
4731 checkGLcall("glDepthRange");
4732 /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
4734 if (context->render_offscreen)
4736 glViewport(vp.X, vp.Y, vp.Width, vp.Height);
4738 target->get_drawable_size(context, &width, &height);
4741 (height - (vp.Y + vp.Height)),
4742 vp.Width, vp.Height);
4745 checkGLcall("glViewport");
4748 static void viewport_vertexpart(DWORD state_id, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4750 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4751 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4753 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
4754 state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
4756 /* Update the position fixup. */
4757 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
4758 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
4761 static void light(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4763 UINT Index = state - STATE_ACTIVELIGHT(0);
4764 const struct wined3d_light_info *lightInfo = stateblock->state.lights[Index];
4767 glDisable(GL_LIGHT0 + Index);
4768 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4771 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4773 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4774 glMatrixMode(GL_MODELVIEW);
4776 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
4779 colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
4780 colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
4781 colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
4782 colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
4783 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4784 checkGLcall("glLightfv");
4787 colRGBA[0] = lightInfo->OriginalParms.Specular.r;
4788 colRGBA[1] = lightInfo->OriginalParms.Specular.g;
4789 colRGBA[2] = lightInfo->OriginalParms.Specular.b;
4790 colRGBA[3] = lightInfo->OriginalParms.Specular.a;
4791 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4792 checkGLcall("glLightfv");
4795 colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
4796 colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
4797 colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
4798 colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
4799 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4800 checkGLcall("glLightfv");
4802 if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
4803 quad_att = 1.4f/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
4805 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4808 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4809 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4810 * Attenuation0 to NaN and crashes in the gl lib
4813 switch (lightInfo->OriginalParms.Type) {
4814 case WINED3DLIGHT_POINT:
4816 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4817 checkGLcall("glLightfv");
4818 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4819 checkGLcall("glLightf");
4820 /* Attenuation - Are these right? guessing... */
4821 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
4822 checkGLcall("glLightf");
4823 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
4824 checkGLcall("glLightf");
4825 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4826 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4827 checkGLcall("glLightf");
4831 case WINED3DLIGHT_SPOT:
4833 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4834 checkGLcall("glLightfv");
4836 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4837 checkGLcall("glLightfv");
4838 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4839 checkGLcall("glLightf");
4840 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4841 checkGLcall("glLightf");
4842 /* Attenuation - Are these right? guessing... */
4843 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
4844 checkGLcall("glLightf");
4845 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
4846 checkGLcall("glLightf");
4847 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4848 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4849 checkGLcall("glLightf");
4853 case WINED3DLIGHT_DIRECTIONAL:
4855 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4856 checkGLcall("glLightfv");
4857 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4858 checkGLcall("glLightf");
4859 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4860 checkGLcall("glLightf");
4864 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
4867 /* Restore the modelview matrix */
4870 glEnable(GL_LIGHT0 + Index);
4871 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4875 static void scissorrect(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4877 struct wined3d_surface *target = stateblock->device->render_targets[0];
4878 RECT *pRect = &stateblock->state.scissor_rect;
4882 target->get_drawable_size(context, &width, &height);
4883 /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
4884 * Warning2: Even in windowed mode the coords are relative to the window, not the screen
4886 TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->device, pRect->left, pRect->bottom - height,
4887 pRect->right - pRect->left, pRect->bottom - pRect->top);
4889 if (context->render_offscreen)
4891 glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
4893 glScissor(pRect->left, height - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
4895 checkGLcall("glScissor");
4898 static void indexbuffer(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4900 const struct wined3d_gl_info *gl_info = context->gl_info;
4902 if (stateblock->state.user_stream || !stateblock->state.index_buffer)
4904 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4908 struct wined3d_buffer *ib = stateblock->state.index_buffer;
4909 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4913 static void frontface(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4915 if (context->render_offscreen)
4917 glFrontFace(GL_CCW);
4918 checkGLcall("glFrontFace(GL_CCW)");
4921 checkGLcall("glFrontFace(GL_CW)");
4925 static void psorigin_w(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4931 WARN("Point sprite coordinate origin switching not supported.\n");
4936 static void psorigin(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
4938 const struct wined3d_gl_info *gl_info = context->gl_info;
4939 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4941 if (glPointParameteri)
4943 glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin);
4944 checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4946 else if (gl_info->supported[NV_POINT_SPRITE])
4948 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4949 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4953 const struct StateEntryTemplate misc_state_template[] = {
4954 { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4955 { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4956 { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4957 { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4958 { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4959 { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4960 { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4961 { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4962 { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4963 { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4964 { STATE_STREAMSRC, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
4965 { STATE_VDECL, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE },
4966 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4967 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4968 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4969 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4971 /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and
4972 * vshader loadings are untied from each other
4974 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4975 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4976 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4977 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4978 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4979 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4980 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4981 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4982 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4983 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4984 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4985 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4986 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4987 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4988 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4989 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4990 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4991 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4992 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4993 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4994 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4995 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4996 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4997 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4998 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4999 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5000 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5001 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5003 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5004 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5005 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5006 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5007 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5008 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5009 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5010 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5011 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5012 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5013 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5014 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5015 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5016 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5017 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5018 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5019 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5020 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5021 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5022 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5023 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5025 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
5026 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
5027 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
5028 { STATE_RENDER(WINED3DRS_ANTIALIAS), { STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
5029 { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
5030 { STATE_RENDER(WINED3DRS_ZENABLE), { STATE_RENDER(WINED3DRS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
5031 { STATE_RENDER(WINED3DRS_WRAPU), { STATE_RENDER(WINED3DRS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
5032 { STATE_RENDER(WINED3DRS_WRAPV), { STATE_RENDER(WINED3DRS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
5033 { STATE_RENDER(WINED3DRS_FILLMODE), { STATE_RENDER(WINED3DRS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
5034 { STATE_RENDER(WINED3DRS_SHADEMODE), { STATE_RENDER(WINED3DRS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
5035 { STATE_RENDER(WINED3DRS_LINEPATTERN), { STATE_RENDER(WINED3DRS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
5036 { STATE_RENDER(WINED3DRS_MONOENABLE), { STATE_RENDER(WINED3DRS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
5037 { STATE_RENDER(WINED3DRS_ROP2), { STATE_RENDER(WINED3DRS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
5038 { STATE_RENDER(WINED3DRS_PLANEMASK), { STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
5039 { STATE_RENDER(WINED3DRS_ZWRITEENABLE), { STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
5040 { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5042 { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5044 { STATE_RENDER(WINED3DRS_LASTPIXEL), { STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
5045 { STATE_RENDER(WINED3DRS_CULLMODE), { STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
5046 { STATE_RENDER(WINED3DRS_ZFUNC), { STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
5047 { STATE_RENDER(WINED3DRS_DITHERENABLE), { STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
5048 { STATE_RENDER(WINED3DRS_SUBPIXEL), { STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3DRS_SUBPIXELX), { STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
5050 { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
5051 { STATE_RENDER(WINED3DRS_STIPPLEENABLE), { STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
5052 { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
5053 { STATE_RENDER(WINED3DRS_ANISOTROPY), { STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
5054 { STATE_RENDER(WINED3DRS_FLUSHBATCH), { STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
5055 { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, WINED3D_GL_EXT_NONE },
5056 { STATE_RENDER(WINED3DRS_STENCILENABLE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
5057 { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5058 { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5059 { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5060 { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5061 { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5062 { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5063 { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
5064 { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
5065 { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5066 { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5067 { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5068 { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5069 { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5070 { STATE_RENDER(WINED3DRS_WRAP0), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5071 { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5072 { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5073 { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5074 { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5075 { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5076 { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5077 { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5078 { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5079 { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5080 { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5081 { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5082 { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5083 { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5084 { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5085 { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5086 { STATE_RENDER(WINED3DRS_EXTENTS), { STATE_RENDER(WINED3DRS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5087 { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5088 { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5089 { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5090 { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5091 { STATE_RENDER(WINED3DRS_POSITIONDEGREE), { STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5092 { STATE_RENDER(WINED3DRS_NORMALDEGREE), { STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5093 { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5094 { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5095 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5096 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5097 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5098 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5099 { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5100 { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
5101 { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5102 { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5103 { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5104 { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5105 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5106 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5107 { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5108 { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5109 { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5110 { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5111 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5112 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5113 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5114 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5115 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5116 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5117 { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5118 { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5119 { STATE_RENDER(WINED3DRS_DEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5120 { STATE_RENDER(WINED3DRS_ZVISIBLE), { STATE_RENDER(WINED3DRS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5122 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5123 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5124 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5125 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5126 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5127 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5128 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5129 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5130 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5131 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5132 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5133 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5134 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5135 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5136 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5137 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5138 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5139 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5140 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5141 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5142 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5145 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5146 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5147 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5148 { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5149 { STATE_RENDER(WINED3DRS_SPECULARENABLE), { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5151 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5152 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5153 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5154 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5155 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5156 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5157 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5158 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5159 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5160 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5161 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5162 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5163 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5164 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5165 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5166 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5167 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5168 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5169 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5170 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5171 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5172 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5173 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5174 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5175 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5176 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5177 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5178 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5179 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5180 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5181 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5182 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5184 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5185 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5186 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5187 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5188 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5189 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5190 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5191 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5193 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5194 /* Transform states follow */
5195 { STATE_TRANSFORM(WINED3DTS_VIEW), { STATE_TRANSFORM(WINED3DTS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3DTS_PROJECTION), { STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 3)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 4)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 5)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 6)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 7)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 8)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 9)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5396 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5397 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5400 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5401 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5402 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5403 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5405 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5406 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5407 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5411 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5412 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5413 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5414 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5415 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5416 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5417 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5418 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5419 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5420 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5421 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5422 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5423 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5424 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5425 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5426 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5427 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5428 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5429 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5430 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5431 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5432 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5433 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5434 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5435 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5436 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5437 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5438 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5439 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5440 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5441 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5442 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5443 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5444 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5445 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5446 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5447 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5448 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5449 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5450 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5451 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5452 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5453 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5454 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5455 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5456 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5457 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5458 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5459 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5460 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5461 { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5462 { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5463 { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5464 { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5465 { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5466 { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5467 { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5468 { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5469 { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5470 { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5471 { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5472 { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5473 { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5474 { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5475 { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5476 { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5478 { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5479 { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5480 { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5481 { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog }, NV_FOG_DISTANCE },
5482 { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog_w }, WINED3D_GL_EXT_NONE },
5483 { STATE_RENDER(WINED3DRS_CLIPPING), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5484 { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5485 { STATE_RENDER(WINED3DRS_LIGHTING), { STATE_RENDER(WINED3DRS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5486 { STATE_RENDER(WINED3DRS_AMBIENT), { STATE_RENDER(WINED3DRS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5487 { STATE_RENDER(WINED3DRS_COLORVERTEX), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5488 { STATE_RENDER(WINED3DRS_LOCALVIEWER), { STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5489 { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5490 { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5491 { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5492 { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5493 { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5494 { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5495 { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5496 { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5497 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5498 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5499 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5500 { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5501 { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5502 { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5503 { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5504 { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5505 { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5506 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5507 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5508 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5509 { STATE_RENDER(WINED3DRS_TWEENFACTOR), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5510 { STATE_RENDER(WINED3DRS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5512 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5513 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5514 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5516 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5517 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5518 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5519 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5520 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5521 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5522 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5523 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5524 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5525 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5526 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5527 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5528 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5529 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5530 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5531 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5532 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5533 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5534 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5535 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5536 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5537 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5538 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5539 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5540 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5543 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5544 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5545 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5546 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5547 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5548 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5549 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5550 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5551 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5552 { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5553 { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5554 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5555 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5556 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5557 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5558 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5559 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5560 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5561 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5562 { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5563 { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5564 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5565 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5566 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5567 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5568 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5569 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5570 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5571 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5572 { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5573 { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5574 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5575 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5576 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5577 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5578 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5579 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5580 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5581 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5582 { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5583 { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5584 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5585 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5586 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5587 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5588 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5589 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5590 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5591 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5592 { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5593 { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5594 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5595 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5596 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5597 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5598 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5599 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5600 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5601 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5602 { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5603 { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5604 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5605 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5606 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5607 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5608 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5609 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5610 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5611 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5612 { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5613 { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5614 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5615 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5616 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5617 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5618 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5619 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5620 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5621 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5622 { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5623 { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5624 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5625 { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5626 { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5627 { STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5628 { STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5629 { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5630 { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5631 { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5632 { STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5633 { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5634 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5635 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5636 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5637 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5638 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5639 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5640 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5641 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5642 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5645 /* Context activation is done by the caller. */
5646 static void ffp_enable(BOOL enable) {}
5648 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5650 caps->PrimitiveMiscCaps = 0;
5651 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5652 | WINED3DTEXOPCAPS_ADDSIGNED
5653 | WINED3DTEXOPCAPS_ADDSIGNED2X
5654 | WINED3DTEXOPCAPS_MODULATE
5655 | WINED3DTEXOPCAPS_MODULATE2X
5656 | WINED3DTEXOPCAPS_MODULATE4X
5657 | WINED3DTEXOPCAPS_SELECTARG1
5658 | WINED3DTEXOPCAPS_SELECTARG2
5659 | WINED3DTEXOPCAPS_DISABLE;
5661 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5662 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5663 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5665 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5666 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5667 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5668 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5669 | WINED3DTEXOPCAPS_LERP
5670 | WINED3DTEXOPCAPS_SUBTRACT;
5672 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5673 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5675 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5676 | WINED3DTEXOPCAPS_MULTIPLYADD
5677 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5678 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5679 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5681 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5682 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5684 caps->MaxTextureBlendStages = gl_info->limits.textures;
5685 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5688 static HRESULT ffp_fragment_alloc(IWineD3DDeviceImpl *device) { return WINED3D_OK; }
5689 static void ffp_fragment_free(IWineD3DDeviceImpl *device) {}
5690 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5694 TRACE("Checking support for fixup:\n");
5695 dump_color_fixup_desc(fixup);
5698 /* We only support identity conversions. */
5699 if (is_identity_fixup(fixup))
5705 TRACE("[FAILED]\n");
5709 const struct fragment_pipeline ffp_fragment_pipeline = {
5711 ffp_fragment_get_caps,
5714 ffp_color_fixup_supported,
5715 ffp_fragmentstate_template,
5716 FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5719 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5722 for(i = 0; funcs[i]; i++);
5726 static void multistate_apply_2(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
5728 stateblock->device->multistate_funcs[state][0](state, stateblock, context);
5729 stateblock->device->multistate_funcs[state][1](state, stateblock, context);
5732 static void multistate_apply_3(DWORD state, struct wined3d_stateblock *stateblock, struct wined3d_context *context)
5734 stateblock->device->multistate_funcs[state][0](state, stateblock, context);
5735 stateblock->device->multistate_funcs[state][1](state, stateblock, context);
5736 stateblock->device->multistate_funcs[state][2](state, stateblock, context);
5739 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5741 unsigned int start, last, i;
5743 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5744 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5745 for (i = start; i <= last; ++i)
5747 state_table[i].representative = 0;
5748 state_table[i].apply = state_undefined;
5751 start = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + gl_info->limits.texture_stages);
5752 last = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + MAX_TEXTURES - 1);
5753 for (i = start; i <= last; ++i)
5755 state_table[i].representative = 0;
5756 state_table[i].apply = state_undefined;
5759 start = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(gl_info->limits.blends));
5760 last = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255));
5761 for (i = start; i <= last; ++i)
5763 state_table[i].representative = 0;
5764 state_table[i].apply = state_undefined;
5768 static void validate_state_table(struct StateEntry *state_table)
5790 static const DWORD simple_states[] =
5796 STATE_VERTEXSHADERCONSTANT,
5797 STATE_PIXELSHADERCONSTANT,
5803 STATE_POINTSPRITECOORDORIGIN,
5805 unsigned int i, current;
5807 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5809 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5811 if (!state_table[i].representative)
5812 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5814 else if (state_table[i].representative)
5815 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5817 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5820 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5822 if (!state_table[simple_states[i]].representative)
5823 ERR("State %s (%#x) should have a representative.\n",
5824 debug_d3dstate(simple_states[i]), simple_states[i]);
5827 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5829 DWORD rep = state_table[i].representative;
5832 if (state_table[rep].representative != rep)
5834 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5835 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5836 state_table[i].representative = 0;
5841 if (state_table[i].apply)
5842 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5844 else if (!state_table[i].apply)
5846 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5852 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5853 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5854 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5856 unsigned int i, type, handlers;
5857 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5858 const struct StateEntryTemplate *cur;
5859 BOOL set[STATE_HIGHEST + 1];
5861 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5863 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5864 StateTable[i].representative = 0;
5865 StateTable[i].apply = state_undefined;
5868 for(type = 0; type < 3; type++) {
5869 /* This switch decides the order in which the states are applied */
5871 case 0: cur = misc; break;
5872 case 1: cur = fragment->states; break;
5873 case 2: cur = vertex; break;
5874 default: cur = NULL; /* Stupid compiler */
5878 /* GL extension filtering should not prevent multiple handlers being applied from different
5881 memset(set, 0, sizeof(set));
5883 for(i = 0; cur[i].state; i++) {
5884 APPLYSTATEFUNC *funcs_array;
5886 /* Only use the first matching state with the available extension from one template.
5888 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5889 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5891 * if GL_XYZ_fancy is supported, ignore the 2nd line
5893 if(set[cur[i].state]) continue;
5894 /* Skip state lines depending on unsupported extensions */
5895 if (!gl_info->supported[cur[i].extension]) continue;
5896 set[cur[i].state] = TRUE;
5897 /* In some cases having an extension means that nothing has to be
5898 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5899 * supported, the texture coordinate fixup can be ignored. If the
5900 * apply function is used, mark the state set(done above) to prevent
5901 * applying later lines, but do not record anything in the state
5904 if (!cur[i].content.representative) continue;
5906 handlers = num_handlers(multistate_funcs[cur[i].state]);
5907 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5910 StateTable[cur[i].state].apply = cur[i].content.apply;
5913 StateTable[cur[i].state].apply = multistate_apply_2;
5914 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5916 sizeof(**dev_multistate_funcs) * 2);
5917 if (!dev_multistate_funcs[cur[i].state]) {
5921 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5922 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5925 StateTable[cur[i].state].apply = multistate_apply_3;
5926 funcs_array = HeapReAlloc(GetProcessHeap(),
5928 dev_multistate_funcs[cur[i].state],
5929 sizeof(**dev_multistate_funcs) * 3);
5934 dev_multistate_funcs[cur[i].state] = funcs_array;
5935 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5938 ERR("Unexpected amount of state handlers for state %u: %u\n",
5939 cur[i].state, handlers + 1);
5942 if(StateTable[cur[i].state].representative &&
5943 StateTable[cur[i].state].representative != cur[i].content.representative) {
5944 FIXME("State %u has different representatives in different pipeline parts\n",
5947 StateTable[cur[i].state].representative = cur[i].content.representative;
5951 prune_invalid_states(StateTable, gl_info);
5952 validate_state_table(StateTable);
5957 for (i = 0; i <= STATE_HIGHEST; ++i) {
5958 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5961 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5963 return E_OUTOFMEMORY;