wined3d: Directly pass the texture to texture_activate_dimensions().
[wine.git] / dlls / wined3d / state.c
blob1e49d3630da719d7ddc92878be965bd19bba8ad5
1 /*
2 * Direct3D state management
4 * Copyright 2002 Lionel Ulmer
5 * Copyright 2002-2005 Jason Edmeades
6 * Copyright 2003-2004 Raphael Junqueira
7 * Copyright 2004 Christian Costa
8 * Copyright 2005 Oliver Stieber
9 * Copyright 2006 Henri Verbeet
10 * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
11 * Copyright 2009 Henri Verbeet for CodeWeavers
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "config.h"
29 #include <stdio.h>
30 #ifdef HAVE_FLOAT_H
31 # include <float.h>
32 #endif
33 #include "wined3d_private.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
36 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
38 /* GL locking for state handlers is done by the caller. */
40 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
42 static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
44 ERR("Undefined state.\n");
47 static void state_nop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
49 TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state));
52 static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
54 WINED3DFILLMODE Value = stateblock->state.render_states[WINED3DRS_FILLMODE];
56 switch(Value) {
57 case WINED3DFILL_POINT:
58 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
59 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
60 break;
61 case WINED3DFILL_WIREFRAME:
62 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
63 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
64 break;
65 case WINED3DFILL_SOLID:
66 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
67 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
68 break;
69 default:
70 FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
74 static void state_lighting(DWORD state, IWineD3DStateBlockImpl *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)) {
83 return;
86 if (stateblock->state.render_states[WINED3DRS_LIGHTING]
87 && !stateblock->device->strided_streams.position_transformed)
89 glEnable(GL_LIGHTING);
90 checkGLcall("glEnable GL_LIGHTING");
91 } else {
92 glDisable(GL_LIGHTING);
93 checkGLcall("glDisable GL_LIGHTING");
97 static void state_zenable(DWORD state, IWineD3DStateBlockImpl *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");
105 return;
108 switch (stateblock->state.render_states[WINED3DRS_ZENABLE])
110 case WINED3DZB_FALSE:
111 glDisable(GL_DEPTH_TEST);
112 checkGLcall("glDisable GL_DEPTH_TEST");
113 break;
114 case WINED3DZB_TRUE:
115 glEnable(GL_DEPTH_TEST);
116 checkGLcall("glEnable GL_DEPTH_TEST");
117 break;
118 case WINED3DZB_USEW:
119 glEnable(GL_DEPTH_TEST);
120 checkGLcall("glEnable GL_DEPTH_TEST");
121 FIXME("W buffer is not well handled\n");
122 break;
123 default:
124 FIXME("Unrecognized D3DZBUFFERTYPE value %#x.\n",
125 stateblock->state.render_states[WINED3DRS_ZENABLE]);
129 static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *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");
138 break;
139 case WINED3DCULL_CW:
140 glEnable(GL_CULL_FACE);
141 checkGLcall("glEnable GL_CULL_FACE");
142 glCullFace(GL_FRONT);
143 checkGLcall("glCullFace(GL_FRONT)");
144 break;
145 case WINED3DCULL_CCW:
146 glEnable(GL_CULL_FACE);
147 checkGLcall("glEnable GL_CULL_FACE");
148 glCullFace(GL_BACK);
149 checkGLcall("glCullFace(GL_BACK)");
150 break;
151 default:
152 FIXME("Unrecognized/Unhandled WINED3DCULL value %#x.\n",
153 stateblock->state.render_states[WINED3DRS_CULLMODE]);
157 static void state_shademode(DWORD state, IWineD3DStateBlockImpl *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)");
164 break;
165 case WINED3DSHADE_GOURAUD:
166 glShadeModel(GL_SMOOTH);
167 checkGLcall("glShadeModel(GL_SMOOTH)");
168 break;
169 case WINED3DSHADE_PHONG:
170 FIXME("WINED3DSHADE_PHONG isn't supported\n");
171 break;
172 default:
173 FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %#x.\n",
174 stateblock->state.render_states[WINED3DRS_SHADEMODE]);
178 static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
180 if (stateblock->state.render_states[WINED3DRS_DITHERENABLE])
182 glEnable(GL_DITHER);
183 checkGLcall("glEnable GL_DITHER");
185 else
187 glDisable(GL_DITHER);
188 checkGLcall("glDisable GL_DITHER");
192 static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *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])
198 glDepthMask(1);
199 checkGLcall("glDepthMask(1)");
201 else
203 glDepthMask(0);
204 checkGLcall("glDepthMask(0)");
208 static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *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)
216 static BOOL once;
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. */
222 if (!once)
224 once = TRUE;
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, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
235 float col[4];
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, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
245 IWineD3DSurfaceImpl *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))
262 glDisable(GL_BLEND);
263 checkGLcall("glDisable GL_BLEND");
264 return;
265 } else {
266 glEnable(GL_BLEND);
267 checkGLcall("glEnable GL_BLEND");
269 } else {
270 glDisable(GL_BLEND);
271 checkGLcall("glDisable GL_BLEND");
272 /* Nothing more to do - get out */
273 return;
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;
294 break;
295 case WINED3DBLEND_INVDESTALPHA :
296 dstBlend = target->resource.format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
297 break;
299 case WINED3DBLEND_SRCALPHASAT :
300 dstBlend = GL_SRC_ALPHA_SATURATE;
301 WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
302 break;
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");
310 break;
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");
315 break;
317 case WINED3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR; break;
318 case WINED3DBLEND_INVBLENDFACTOR : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
319 default:
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;
338 break;
339 case WINED3DBLEND_INVDESTALPHA :
340 srcBlend = target->resource.format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
341 break;
343 case WINED3DBLEND_BOTHSRCALPHA : srcBlend = GL_SRC_ALPHA;
344 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
345 break;
347 case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
348 dstBlend = GL_SRC_ALPHA;
349 break;
351 case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR; break;
352 case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
353 default:
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");
369 } else {
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");
388 return;
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");
406 break;
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");
414 break;
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");
419 break;
420 case WINED3DBLEND_BLENDFACTOR : dstBlendAlpha = GL_CONSTANT_COLOR; break;
421 case WINED3DBLEND_INVBLENDFACTOR : dstBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR; break;
422 default:
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;
443 break;
444 case WINED3DBLEND_BOTHINVSRCALPHA :
445 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
446 dstBlendAlpha = GL_SRC_ALPHA;
447 break;
448 case WINED3DBLEND_BLENDFACTOR : srcBlendAlpha = GL_CONSTANT_COLOR; break;
449 case WINED3DBLEND_INVBLENDFACTOR : srcBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR; break;
450 default:
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");
457 } else {
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, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
471 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
474 static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
476 const struct wined3d_gl_info *gl_info = context->gl_info;
477 float col[4];
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, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
487 int glParm = 0;
488 float ref;
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 IWineD3DBaseTextureImpl *texture = stateblock->state.textures[0];
502 GLenum texture_dimensions = texture->baseTexture.target;
504 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
506 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.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");
527 } else {
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
531 * enable call
533 return;
536 if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && enable_ckey)
538 glParm = GL_NOTEQUAL;
539 ref = 0.0f;
540 } else {
541 ref = ((float)stateblock->state.render_states[WINED3DRS_ALPHAREF]) / 255.0f;
542 glParm = CompareFunc(stateblock->state.render_states[WINED3DRS_ALPHAFUNC]);
544 if(glParm) {
545 glAlphaFunc(glParm, ref);
546 checkGLcall("glAlphaFunc");
550 static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
552 const struct wined3d_gl_info *gl_info = context->gl_info;
553 DWORD enable = 0xFFFFFFFF;
554 DWORD disable = 0x00000000;
556 if (!stateblock->device->vs_clipping && use_vs(stateblock))
558 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
559 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
560 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
561 * of that - don't do anything here and keep them disabled
563 if (stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
565 static BOOL warned = FALSE;
566 if(!warned) {
567 FIXME("Clipping not supported with vertex shaders\n");
568 warned = TRUE;
571 return;
574 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
575 * of already set values
578 /* If enabling / disabling all
579 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
581 if (stateblock->state.render_states[WINED3DRS_CLIPPING])
583 enable = stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE];
584 disable = ~stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE];
585 if (gl_info->supported[ARB_DEPTH_CLAMP])
587 glDisable(GL_DEPTH_CLAMP);
588 checkGLcall("glDisable(GL_DEPTH_CLAMP)");
590 } else {
591 disable = 0xffffffff;
592 enable = 0x00;
593 if (gl_info->supported[ARB_DEPTH_CLAMP])
595 glEnable(GL_DEPTH_CLAMP);
596 checkGLcall("glEnable(GL_DEPTH_CLAMP)");
598 else
600 FIXME("Clipping disabled, but ARB_depth_clamp isn't supported.\n");
604 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
605 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
606 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
607 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
608 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
609 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
611 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
612 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
613 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
614 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
615 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
616 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
618 /** update clipping status */
619 if (enable)
621 stateblock->state.clip_status.ClipUnion = 0;
622 stateblock->state.clip_status.ClipIntersection = 0xFFFFFFFF;
624 else
626 stateblock->state.clip_status.ClipUnion = 0;
627 stateblock->state.clip_status.ClipIntersection = 0;
631 static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
633 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
636 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
638 const struct wined3d_gl_info *gl_info = context->gl_info;
639 int blendEquation = GL_FUNC_ADD;
640 int blendEquationAlpha = GL_FUNC_ADD;
642 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
643 if (stateblock->state.render_states[WINED3DRS_BLENDOPALPHA]
644 && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
646 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
647 return;
650 switch (stateblock->state.render_states[WINED3DRS_BLENDOP])
652 case WINED3DBLENDOP_ADD : blendEquation = GL_FUNC_ADD; break;
653 case WINED3DBLENDOP_SUBTRACT : blendEquation = GL_FUNC_SUBTRACT; break;
654 case WINED3DBLENDOP_REVSUBTRACT : blendEquation = GL_FUNC_REVERSE_SUBTRACT; break;
655 case WINED3DBLENDOP_MIN : blendEquation = GL_MIN; break;
656 case WINED3DBLENDOP_MAX : blendEquation = GL_MAX; break;
657 default:
658 FIXME("Unrecognized/Unhandled D3DBLENDOP value %#x.\n",
659 stateblock->state.render_states[WINED3DRS_BLENDOP]);
662 switch (stateblock->state.render_states[WINED3DRS_BLENDOPALPHA])
664 case WINED3DBLENDOP_ADD : blendEquationAlpha = GL_FUNC_ADD; break;
665 case WINED3DBLENDOP_SUBTRACT : blendEquationAlpha = GL_FUNC_SUBTRACT; break;
666 case WINED3DBLENDOP_REVSUBTRACT : blendEquationAlpha = GL_FUNC_REVERSE_SUBTRACT; break;
667 case WINED3DBLENDOP_MIN : blendEquationAlpha = GL_MIN; break;
668 case WINED3DBLENDOP_MAX : blendEquationAlpha = GL_MAX; break;
669 default:
670 FIXME("Unrecognized/Unhandled D3DBLENDOP value %#x\n",
671 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");
679 } else {
680 TRACE("glBlendEquation(%x)\n", blendEquation);
681 GL_EXTCALL(glBlendEquationEXT(blendEquation));
682 checkGLcall("glBlendEquation");
686 static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *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
694 * some extent.
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
697 * running 1.4 yet!
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);
736 else
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);
746 else
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()");
757 } else {
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);
769 else
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, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
805 const struct wined3d_gl_info *gl_info = context->gl_info;
806 unsigned int i;
808 /* Note the texture color applies to all textures whereas
809 * GL_TEXTURE_ENV_COLOR applies to active only
811 float col[4];
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, IWineD3DStateBlockImpl *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;
850 GLint ref = 0;
851 GLuint mask = 0;
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");
864 return;
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])))
870 func = GL_ALWAYS;
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
899 * to set it back
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, ...)");
914 } else {
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(...)");
935 } else {
936 glDisable(GL_STENCIL_TEST);
937 checkGLcall("glDisable GL_STENCIL_TEST");
941 static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *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)");
948 glStencilMask(mask);
949 checkGLcall("glStencilMask");
950 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
951 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
952 glStencilMask(mask);
955 static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
957 DWORD mask = stateblock->device->depth_stencil ? stateblock->state.render_states[WINED3DRS_STENCILWRITEMASK] : 0;
959 glStencilMask(mask);
960 checkGLcall("glStencilMask");
963 static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *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;
979 return;
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;
993 } else {
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, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1005 float fogstart, fogend;
1006 union {
1007 DWORD d;
1008 float f;
1009 } tmpvalue;
1011 switch(context->fog_source) {
1012 case FOGSOURCE_VS:
1013 fogstart = 1.0f;
1014 fogend = 0.0f;
1015 break;
1017 case FOGSOURCE_COORD:
1018 fogstart = 255.0f;
1019 fogend = 0.0f;
1020 break;
1022 case FOGSOURCE_FFP:
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;
1030 fogend = 0.0f;
1032 break;
1034 default:
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");
1039 fogstart = 0.0f;
1040 fogend = 0.0f;
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, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1054 enum fogsource new_source;
1056 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
1058 if (!stateblock->state.render_states[WINED3DRS_FOGENABLE])
1060 /* No fog? Disable it, and we're done :-) */
1061 glDisableWINE(GL_FOG);
1062 checkGLcall("glDisable GL_FOG");
1063 return;
1066 /* Fog Rules:
1068 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1069 * It can use the Z value of the vertex, or the alpha component of the specular color.
1070 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1071 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1072 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1074 * FOGTABLEMODE != NONE:
1075 * The Z value is used, with the equation specified, no matter what vertex type.
1077 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1078 * Per vertex fog is calculated using the specified fog equation and the parameters
1080 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1081 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1082 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1085 * Rules for vertex fog with shaders:
1087 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1088 * the fog computation to happen during transformation while openGL expects it to happen
1089 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1090 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1091 * To solve this problem, WineD3D does:
1092 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1093 * shader,
1094 * and 2) disables the fog computation (in either the fixed function or programmable
1095 * rasterizer) if using a vertex program.
1097 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1098 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1099 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1100 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1101 * There are some GL differences between specular fog coords and vertex shaders though.
1103 * With table fog the vertex shader fog coordinate is ignored.
1105 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1106 * without shaders).
1109 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1110 * the system will apply only pixel(=table) fog effects."
1112 if (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE)
1114 if(use_vs(stateblock)) {
1115 glFogi(GL_FOG_MODE, GL_LINEAR);
1116 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1117 new_source = FOGSOURCE_VS;
1118 } else {
1119 switch (stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE])
1121 /* If processed vertices are used, fall through to the NONE case */
1122 case WINED3DFOG_EXP:
1123 if(!context->last_was_rhw) {
1124 glFogi(GL_FOG_MODE, GL_EXP);
1125 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1126 new_source = FOGSOURCE_FFP;
1127 break;
1129 /* drop through */
1131 case WINED3DFOG_EXP2:
1132 if(!context->last_was_rhw) {
1133 glFogi(GL_FOG_MODE, GL_EXP2);
1134 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1135 new_source = FOGSOURCE_FFP;
1136 break;
1138 /* drop through */
1140 case WINED3DFOG_LINEAR:
1141 if(!context->last_was_rhw) {
1142 glFogi(GL_FOG_MODE, GL_LINEAR);
1143 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1144 new_source = FOGSOURCE_FFP;
1145 break;
1147 /* drop through */
1149 case WINED3DFOG_NONE:
1150 /* Both are none? According to msdn the alpha channel of the specular
1151 * color contains a fog factor. Set it in drawStridedSlow.
1152 * Same happens with Vertexfog on transformed vertices
1154 new_source = FOGSOURCE_COORD;
1155 glFogi(GL_FOG_MODE, GL_LINEAR);
1156 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1157 break;
1159 default:
1160 FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %#x.\n",
1161 stateblock->state.render_states[WINED3DRS_FOGVERTEXMODE]);
1162 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1165 } else {
1166 new_source = FOGSOURCE_FFP;
1168 switch (stateblock->state.render_states[WINED3DRS_FOGTABLEMODE])
1170 case WINED3DFOG_EXP:
1171 glFogi(GL_FOG_MODE, GL_EXP);
1172 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1173 break;
1175 case WINED3DFOG_EXP2:
1176 glFogi(GL_FOG_MODE, GL_EXP2);
1177 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1178 break;
1180 case WINED3DFOG_LINEAR:
1181 glFogi(GL_FOG_MODE, GL_LINEAR);
1182 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1183 break;
1185 case WINED3DFOG_NONE: /* Won't happen */
1186 default:
1187 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %#x.\n",
1188 stateblock->state.render_states[WINED3DRS_FOGTABLEMODE]);
1192 glEnableWINE(GL_FOG);
1193 checkGLcall("glEnable GL_FOG");
1194 if(new_source != context->fog_source) {
1195 context->fog_source = new_source;
1196 state_fogstartend(STATE_RENDER(WINED3DRS_FOGSTART), stateblock, context);
1200 static void state_rangefog_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1202 if (stateblock->state.render_states[WINED3DRS_RANGEFOGENABLE])
1203 WARN("Range fog enabled, but not supported by this opengl implementation\n");
1206 static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1208 if (stateblock->state.render_states[WINED3DRS_RANGEFOGENABLE])
1210 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1211 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1212 } else {
1213 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1214 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1218 void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1220 float col[4];
1221 D3DCOLORTOGLFLOAT4(stateblock->state.render_states[WINED3DRS_FOGCOLOR], col);
1222 glFogfv(GL_FOG_COLOR, &col[0]);
1223 checkGLcall("glFog GL_FOG_COLOR");
1226 void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1228 union {
1229 DWORD d;
1230 float f;
1231 } tmpvalue;
1232 tmpvalue.d = stateblock->state.render_states[WINED3DRS_FOGDENSITY];
1233 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1234 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1237 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1239 IWineD3DDeviceImpl *device = stateblock->device;
1240 GLenum Parm = 0;
1242 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1243 * The vertex declaration will call this function if the fixed function pipeline is used.
1246 if(isStateDirty(context, STATE_VDECL)) {
1247 return;
1250 context->num_untracked_materials = 0;
1251 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1252 && stateblock->state.render_states[WINED3DRS_COLORVERTEX])
1254 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1255 stateblock->state.render_states[WINED3DRS_DIFFUSEMATERIALSOURCE],
1256 stateblock->state.render_states[WINED3DRS_AMBIENTMATERIALSOURCE],
1257 stateblock->state.render_states[WINED3DRS_EMISSIVEMATERIALSOURCE],
1258 stateblock->state.render_states[WINED3DRS_SPECULARMATERIALSOURCE]);
1260 if (stateblock->state.render_states[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1)
1262 if (stateblock->state.render_states[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1)
1264 Parm = GL_AMBIENT_AND_DIFFUSE;
1265 } else {
1266 Parm = GL_DIFFUSE;
1268 if (stateblock->state.render_states[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1)
1270 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1271 context->num_untracked_materials++;
1273 if (stateblock->state.render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1)
1275 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1276 context->num_untracked_materials++;
1279 else if (stateblock->state.render_states[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1)
1281 Parm = GL_AMBIENT;
1282 if (stateblock->state.render_states[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1)
1284 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1285 context->num_untracked_materials++;
1287 if (stateblock->state.render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1)
1289 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1290 context->num_untracked_materials++;
1293 else if (stateblock->state.render_states[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1)
1295 Parm = GL_EMISSION;
1296 if (stateblock->state.render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1)
1298 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1299 context->num_untracked_materials++;
1302 else if (stateblock->state.render_states[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1)
1304 Parm = GL_SPECULAR;
1308 /* Nothing changed, return. */
1309 if (Parm == context->tracking_parm) return;
1311 if(!Parm) {
1312 glDisable(GL_COLOR_MATERIAL);
1313 checkGLcall("glDisable GL_COLOR_MATERIAL");
1314 } else {
1315 glColorMaterial(GL_FRONT_AND_BACK, Parm);
1316 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1317 glEnable(GL_COLOR_MATERIAL);
1318 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1321 /* Apparently calls to glMaterialfv are ignored for properties we're
1322 * tracking with glColorMaterial, so apply those here. */
1323 switch (context->tracking_parm) {
1324 case GL_AMBIENT_AND_DIFFUSE:
1325 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&device->updateStateBlock->state.material.Ambient);
1326 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&device->updateStateBlock->state.material.Diffuse);
1327 checkGLcall("glMaterialfv");
1328 break;
1330 case GL_DIFFUSE:
1331 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&device->updateStateBlock->state.material.Diffuse);
1332 checkGLcall("glMaterialfv");
1333 break;
1335 case GL_AMBIENT:
1336 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&device->updateStateBlock->state.material.Ambient);
1337 checkGLcall("glMaterialfv");
1338 break;
1340 case GL_EMISSION:
1341 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&device->updateStateBlock->state.material.Emissive);
1342 checkGLcall("glMaterialfv");
1343 break;
1345 case GL_SPECULAR:
1346 /* Only change material color if specular is enabled, otherwise it is set to black */
1347 if (device->stateBlock->state.render_states[WINED3DRS_SPECULARENABLE])
1349 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
1350 (float *)&device->updateStateBlock->state.material.Specular);
1351 checkGLcall("glMaterialfv");
1352 } else {
1353 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1354 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1355 checkGLcall("glMaterialfv");
1357 break;
1360 context->tracking_parm = Parm;
1363 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1365 union {
1366 DWORD d;
1367 WINED3DLINEPATTERN lp;
1368 } tmppattern;
1369 tmppattern.d = stateblock->state.render_states[WINED3DRS_LINEPATTERN];
1371 TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1373 if (tmppattern.lp.wRepeatFactor) {
1374 glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1375 checkGLcall("glLineStipple(repeat, linepattern)");
1376 glEnable(GL_LINE_STIPPLE);
1377 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1378 } else {
1379 glDisable(GL_LINE_STIPPLE);
1380 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1384 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1386 union {
1387 DWORD d;
1388 float f;
1389 } tmpvalue;
1391 if (stateblock->state.render_states[WINED3DRS_ZBIAS])
1393 tmpvalue.d = stateblock->state.render_states[WINED3DRS_ZBIAS];
1394 TRACE("ZBias value %f\n", tmpvalue.f);
1395 glPolygonOffset(0, -tmpvalue.f);
1396 checkGLcall("glPolygonOffset(0, -Value)");
1397 glEnable(GL_POLYGON_OFFSET_FILL);
1398 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
1399 glEnable(GL_POLYGON_OFFSET_LINE);
1400 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
1401 glEnable(GL_POLYGON_OFFSET_POINT);
1402 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
1403 } else {
1404 glDisable(GL_POLYGON_OFFSET_FILL);
1405 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
1406 glDisable(GL_POLYGON_OFFSET_LINE);
1407 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
1408 glDisable(GL_POLYGON_OFFSET_POINT);
1409 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
1414 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1416 if(isStateDirty(context, STATE_VDECL)) {
1417 return;
1419 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1420 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1421 * by zero and is not properly defined in opengl, so avoid it
1423 if (stateblock->state.render_states[WINED3DRS_NORMALIZENORMALS]
1424 && (stateblock->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1426 glEnable(GL_NORMALIZE);
1427 checkGLcall("glEnable(GL_NORMALIZE);");
1428 } else {
1429 glDisable(GL_NORMALIZE);
1430 checkGLcall("glDisable(GL_NORMALIZE);");
1434 static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1436 union {
1437 DWORD d;
1438 float f;
1439 } tmpvalue;
1441 tmpvalue.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MIN];
1442 if (tmpvalue.f != 1.0f)
1444 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1446 tmpvalue.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MAX];
1447 if (tmpvalue.f != 64.0f)
1449 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1454 static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1456 const struct wined3d_gl_info *gl_info = context->gl_info;
1457 union
1459 DWORD d;
1460 float f;
1461 } min, max;
1463 min.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MIN];
1464 max.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MAX];
1466 /* Max point size trumps min point size */
1467 if(min.f > max.f) {
1468 min.f = max.f;
1471 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1472 checkGLcall("glPointParameterfEXT(...)");
1473 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1474 checkGLcall("glPointParameterfEXT(...)");
1477 static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1479 const struct wined3d_gl_info *gl_info = context->gl_info;
1480 union
1482 DWORD d;
1483 float f;
1484 } min, max;
1486 min.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MIN];
1487 max.d = stateblock->state.render_states[WINED3DRS_POINTSIZE_MAX];
1489 /* Max point size trumps min point size */
1490 if(min.f > max.f) {
1491 min.f = max.f;
1494 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1495 checkGLcall("glPointParameterfARB(...)");
1496 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1497 checkGLcall("glPointParameterfARB(...)");
1500 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1502 const struct wined3d_gl_info *gl_info = context->gl_info;
1503 /* TODO: Group this with the viewport */
1505 * POINTSCALEENABLE controls how point size value is treated. If set to
1506 * true, the point size is scaled with respect to height of viewport.
1507 * When set to false point size is in pixels.
1510 /* Default values */
1511 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1512 union {
1513 DWORD d;
1514 float f;
1515 } pointSize, A, B, C;
1517 pointSize.d = stateblock->state.render_states[WINED3DRS_POINTSIZE];
1518 A.d = stateblock->state.render_states[WINED3DRS_POINTSCALE_A];
1519 B.d = stateblock->state.render_states[WINED3DRS_POINTSCALE_B];
1520 C.d = stateblock->state.render_states[WINED3DRS_POINTSCALE_C];
1522 if (stateblock->state.render_states[WINED3DRS_POINTSCALEENABLE])
1524 GLfloat scaleFactor;
1525 DWORD h = stateblock->state.viewport.Height;
1527 if (pointSize.f < gl_info->limits.pointsize_min)
1529 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1530 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1531 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1532 * are less than 1.0f. scale_factor = 1.0f / point_size.
1534 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1535 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1536 * is 1.0, but then accepts points below that and draws too small points
1538 pointSize.f = gl_info->limits.pointsize_min;
1540 else if(pointSize.f > gl_info->limits.pointsize_max)
1542 /* gl already scales the input to glPointSize,
1543 * d3d scales the result after the point size scale.
1544 * If the point size is bigger than the max size, use the
1545 * scaling to scale it bigger, and set the gl point size to max
1547 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1548 TRACE("scale: %f\n", scaleFactor);
1549 pointSize.f = gl_info->limits.pointsize_max;
1550 } else {
1551 scaleFactor = 1.0f;
1553 scaleFactor = powf(h * scaleFactor, 2);
1555 att[0] = A.f / scaleFactor;
1556 att[1] = B.f / scaleFactor;
1557 att[2] = C.f / scaleFactor;
1560 if (gl_info->supported[ARB_POINT_PARAMETERS])
1562 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1563 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1565 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1567 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1568 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1570 else if(stateblock->state.render_states[WINED3DRS_POINTSCALEENABLE])
1572 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1575 glPointSize(pointSize.f);
1576 checkGLcall("glPointSize(...);");
1579 static void state_debug_monitor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1581 WARN("token: %#x\n", stateblock->state.render_states[WINED3DRS_DEBUGMONITORTOKEN]);
1584 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1586 DWORD mask0 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE];
1587 DWORD mask1 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE1];
1588 DWORD mask2 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE2];
1589 DWORD mask3 = stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE3];
1591 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1592 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1593 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1594 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1595 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1596 glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1597 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1598 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1599 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1600 checkGLcall("glColorMask(...)");
1602 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1603 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1605 FIXME("WINED3DRS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1606 mask0, mask1, mask2, mask3);
1607 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1611 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1613 GL_EXTCALL(glColorMaskIndexedEXT(index,
1614 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1615 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1616 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1617 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1620 static void state_colorwrite0(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1622 set_color_mask(context->gl_info, 0, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE]);
1625 static void state_colorwrite1(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1627 set_color_mask(context->gl_info, 1, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE1]);
1630 static void state_colorwrite2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1632 set_color_mask(context->gl_info, 2, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE2]);
1635 static void state_colorwrite3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1637 set_color_mask(context->gl_info, 3, stateblock->state.render_states[WINED3DRS_COLORWRITEENABLE3]);
1640 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1642 if (stateblock->state.render_states[WINED3DRS_LOCALVIEWER])
1644 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1645 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1646 } else {
1647 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1648 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1652 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1654 if (stateblock->state.render_states[WINED3DRS_LASTPIXEL])
1656 TRACE("Last Pixel Drawing Enabled\n");
1657 } else {
1658 static BOOL warned;
1659 if (!warned) {
1660 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1661 warned = TRUE;
1662 } else {
1663 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1668 static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1670 static BOOL warned;
1672 /* TODO: NV_POINT_SPRITE */
1673 if (!warned && stateblock->state.render_states[WINED3DRS_POINTSPRITEENABLE])
1675 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1676 FIXME("Point sprites not supported\n");
1677 warned = TRUE;
1681 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1683 const struct wined3d_gl_info *gl_info = context->gl_info;
1685 if (stateblock->state.render_states[WINED3DRS_POINTSPRITEENABLE])
1687 static BOOL warned;
1689 if (gl_info->limits.point_sprite_units < gl_info->limits.textures && !warned)
1691 if (use_ps(stateblock) || stateblock->state.lowest_disabled_stage > gl_info->limits.point_sprite_units)
1693 FIXME("The app uses point sprite texture coordinates on more units than supported by the driver\n");
1694 warned = TRUE;
1698 glEnable(GL_POINT_SPRITE_ARB);
1699 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1700 } else {
1701 glDisable(GL_POINT_SPRITE_ARB);
1702 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1706 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1709 http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1710 http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1711 Discussion on the ways to turn on WRAPing to solve an OpenGL conversion problem.
1712 http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1714 so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1716 if (stateblock->state.render_states[WINED3DRS_WRAP0]
1717 || stateblock->state.render_states[WINED3DRS_WRAP1]
1718 || stateblock->state.render_states[WINED3DRS_WRAP2]
1719 || stateblock->state.render_states[WINED3DRS_WRAP3]
1720 || stateblock->state.render_states[WINED3DRS_WRAP4]
1721 || stateblock->state.render_states[WINED3DRS_WRAP5]
1722 || stateblock->state.render_states[WINED3DRS_WRAP6]
1723 || stateblock->state.render_states[WINED3DRS_WRAP7]
1724 || stateblock->state.render_states[WINED3DRS_WRAP8]
1725 || stateblock->state.render_states[WINED3DRS_WRAP9]
1726 || stateblock->state.render_states[WINED3DRS_WRAP10]
1727 || stateblock->state.render_states[WINED3DRS_WRAP11]
1728 || stateblock->state.render_states[WINED3DRS_WRAP12]
1729 || stateblock->state.render_states[WINED3DRS_WRAP13]
1730 || stateblock->state.render_states[WINED3DRS_WRAP14]
1731 || stateblock->state.render_states[WINED3DRS_WRAP15])
1733 FIXME("(WINED3DRS_WRAP0) Texture wrapping not yet supported.\n");
1737 static void state_msaa_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1739 if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEANTIALIAS])
1740 WARN("Multisample antialiasing not supported by gl\n");
1743 static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1745 if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEANTIALIAS])
1747 glEnable(GL_MULTISAMPLE_ARB);
1748 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1749 } else {
1750 glDisable(GL_MULTISAMPLE_ARB);
1751 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1755 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1757 if (stateblock->state.render_states[WINED3DRS_SCISSORTESTENABLE])
1759 glEnable(GL_SCISSOR_TEST);
1760 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1761 } else {
1762 glDisable(GL_SCISSOR_TEST);
1763 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1767 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1768 * OpenGL the bias is specified in units of "the smallest value that is
1769 * guaranteed to produce a resolvable offset for a given implementation". To
1770 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1771 * There's no practical way to retrieve that value from a given GL
1772 * implementation, but the D3D application has essentially the same problem,
1773 * which makes a guess of 1e-6f seem reasonable here. Note that
1774 * SLOPESCALEDEPTHBIAS is a scaling factor for the depth slope, and doesn't
1775 * need to be scaled. */
1776 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1778 if (stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS]
1779 || stateblock->state.render_states[WINED3DRS_DEPTHBIAS])
1781 union
1783 DWORD d;
1784 float f;
1785 } scale_bias, const_bias;
1787 scale_bias.d = stateblock->state.render_states[WINED3DRS_SLOPESCALEDEPTHBIAS];
1788 const_bias.d = stateblock->state.render_states[WINED3DRS_DEPTHBIAS];
1790 glEnable(GL_POLYGON_OFFSET_FILL);
1791 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1793 glPolygonOffset(scale_bias.f, const_bias.f * 1e6f);
1794 checkGLcall("glPolygonOffset(...)");
1795 } else {
1796 glDisable(GL_POLYGON_OFFSET_FILL);
1797 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1801 static void state_zvisible(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1803 if (stateblock->state.render_states[WINED3DRS_ZVISIBLE])
1804 FIXME("WINED3DRS_ZVISIBLE not implemented.\n");
1807 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1809 if (stateblock->state.render_states[WINED3DRS_TEXTUREPERSPECTIVE])
1811 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1812 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1813 } else {
1814 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1815 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1819 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1821 if (stateblock->state.render_states[WINED3DRS_STIPPLEDALPHA])
1822 FIXME(" Stippled Alpha not supported yet.\n");
1825 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1827 if (stateblock->state.render_states[WINED3DRS_ANTIALIAS])
1828 FIXME("Antialias not supported yet.\n");
1831 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1833 if (stateblock->state.render_states[WINED3DRS_MULTISAMPLEMASK] != 0xffffffff)
1834 FIXME("WINED3DRS_MULTISAMPLEMASK %#x not yet implemented.\n",
1835 stateblock->state.render_states[WINED3DRS_MULTISAMPLEMASK]);
1838 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1840 if (stateblock->state.render_states[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
1841 FIXME("WINED3DRS_PATCHEDGESTYLE %#x not yet implemented.\n",
1842 stateblock->state.render_states[WINED3DRS_PATCHEDGESTYLE]);
1845 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1847 union {
1848 DWORD d;
1849 float f;
1850 } tmpvalue;
1851 tmpvalue.f = 1.0f;
1853 if (stateblock->state.render_states[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1855 static BOOL displayed = FALSE;
1857 tmpvalue.d = stateblock->state.render_states[WINED3DRS_PATCHSEGMENTS];
1858 if(!displayed)
1859 FIXME("(WINED3DRS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1861 displayed = TRUE;
1865 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1867 if (stateblock->state.render_states[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
1868 FIXME("WINED3DRS_POSITIONDEGREE %#x not yet implemented.\n",
1869 stateblock->state.render_states[WINED3DRS_POSITIONDEGREE]);
1872 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1874 if (stateblock->state.render_states[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
1875 FIXME("WINED3DRS_NORMALDEGREE %#x not yet implemented.\n",
1876 stateblock->state.render_states[WINED3DRS_NORMALDEGREE]);
1879 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1881 if (stateblock->state.render_states[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1882 FIXME("WINED3DRS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1883 stateblock->state.render_states[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1886 static void state_nvdb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1888 union {
1889 DWORD d;
1890 float f;
1891 } zmin, zmax;
1893 const struct wined3d_gl_info *gl_info = context->gl_info;
1895 if (stateblock->state.render_states[WINED3DRS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1897 zmin.d = stateblock->state.render_states[WINED3DRS_ADAPTIVETESS_Z];
1898 zmax.d = stateblock->state.render_states[WINED3DRS_ADAPTIVETESS_W];
1900 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1901 * In d3d9 test is not performed in this case*/
1902 if (zmin.f <= zmax.f)
1904 glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1905 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1906 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1907 checkGLcall("glDepthBoundsEXT(...)");
1909 else {
1910 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1911 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1914 else {
1915 glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1916 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1919 state_tessellation(state, stateblock, context);
1922 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1924 if (stateblock->state.render_states[WINED3DRS_WRAPU])
1925 FIXME("Render state WINED3DRS_WRAPU not implemented yet.\n");
1928 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1930 if (stateblock->state.render_states[WINED3DRS_WRAPV])
1931 FIXME("Render state WINED3DRS_WRAPV not implemented yet.\n");
1934 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1936 if (stateblock->state.render_states[WINED3DRS_MONOENABLE])
1937 FIXME("Render state WINED3DRS_MONOENABLE not implemented yet.\n");
1940 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1942 if (stateblock->state.render_states[WINED3DRS_ROP2])
1943 FIXME("Render state WINED3DRS_ROP2 not implemented yet.\n");
1946 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1948 if (stateblock->state.render_states[WINED3DRS_PLANEMASK])
1949 FIXME("Render state WINED3DRS_PLANEMASK not implemented yet.\n");
1952 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1954 if (stateblock->state.render_states[WINED3DRS_SUBPIXEL])
1955 FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet.\n");
1958 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1960 if (stateblock->state.render_states[WINED3DRS_SUBPIXELX])
1961 FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet.\n");
1964 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1966 if (stateblock->state.render_states[WINED3DRS_STIPPLEENABLE])
1967 FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet.\n");
1970 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1972 if (stateblock->state.render_states[WINED3DRS_MIPMAPLODBIAS])
1973 FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet.\n");
1976 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1978 if (stateblock->state.render_states[WINED3DRS_ANISOTROPY])
1979 FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet.\n");
1982 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1984 if (stateblock->state.render_states[WINED3DRS_FLUSHBATCH])
1985 FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet.\n");
1988 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1990 if (stateblock->state.render_states[WINED3DRS_TRANSLUCENTSORTINDEPENDENT])
1991 FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
1994 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1996 if (stateblock->state.render_states[WINED3DRS_EXTENTS])
1997 FIXME("Render state WINED3DRS_EXTENTS not implemented yet.\n");
2000 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2002 if (stateblock->state.render_states[WINED3DRS_COLORKEYBLENDENABLE])
2003 FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet.\n");
2006 static void state_swvp(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2008 if (stateblock->state.render_states[WINED3DRS_SOFTWAREVERTEXPROCESSING])
2009 FIXME("Software vertex processing not implemented.\n");
2012 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
2013 #if defined (GL_VERSION_1_3)
2014 # define useext(A) A
2015 #elif defined (GL_EXT_texture_env_combine)
2016 # define useext(A) A##_EXT
2017 #elif defined (GL_ARB_texture_env_combine)
2018 # define useext(A) A##_ARB
2019 #endif
2021 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2022 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2023 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2024 * flag specifies the complement of the input should be used. */
2025 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2026 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2028 /* Calculate the operand */
2029 if (complement) {
2030 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2031 else *operand = GL_ONE_MINUS_SRC_COLOR;
2032 } else {
2033 if (from_alpha) *operand = GL_SRC_ALPHA;
2034 else *operand = GL_SRC_COLOR;
2037 /* Calculate the source */
2038 switch (arg & WINED3DTA_SELECTMASK) {
2039 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2040 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2041 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2042 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2043 case WINED3DTA_SPECULAR:
2045 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2046 * 'Secondary color' and isn't supported until base GL supports it
2047 * There is no concept of temp registers as far as I can tell
2049 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2050 *source = GL_TEXTURE;
2051 break;
2052 default:
2053 FIXME("Unrecognized texture arg %#x\n", arg);
2054 *source = GL_TEXTURE;
2055 break;
2059 /* Setup the texture operations texture stage states */
2060 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2061 BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
2063 GLenum src1, src2, src3;
2064 GLenum opr1, opr2, opr3;
2065 GLenum comb_target;
2066 GLenum src0_target, src1_target, src2_target;
2067 GLenum opr0_target, opr1_target, opr2_target;
2068 GLenum scal_target;
2069 GLenum opr=0, invopr, src3_target, opr3_target;
2070 BOOL Handled = FALSE;
2072 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2074 /* This is called by a state handler which has the gl lock held and a context for the thread */
2076 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2077 the form (a1 <operation> a2). However, some of the more complex operations
2078 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2079 in a third parameter called a0. Therefore these are operations of the form
2080 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2082 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2083 functions below, expect their syntax to differ slightly to those listed in the
2084 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2085 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2087 if (isAlpha) {
2088 comb_target = useext(GL_COMBINE_ALPHA);
2089 src0_target = useext(GL_SOURCE0_ALPHA);
2090 src1_target = useext(GL_SOURCE1_ALPHA);
2091 src2_target = useext(GL_SOURCE2_ALPHA);
2092 opr0_target = useext(GL_OPERAND0_ALPHA);
2093 opr1_target = useext(GL_OPERAND1_ALPHA);
2094 opr2_target = useext(GL_OPERAND2_ALPHA);
2095 scal_target = GL_ALPHA_SCALE;
2097 else {
2098 comb_target = useext(GL_COMBINE_RGB);
2099 src0_target = useext(GL_SOURCE0_RGB);
2100 src1_target = useext(GL_SOURCE1_RGB);
2101 src2_target = useext(GL_SOURCE2_RGB);
2102 opr0_target = useext(GL_OPERAND0_RGB);
2103 opr1_target = useext(GL_OPERAND1_RGB);
2104 opr2_target = useext(GL_OPERAND2_RGB);
2105 scal_target = useext(GL_RGB_SCALE);
2108 /* If a texture stage references an invalid texture unit the stage just
2109 * passes through the result from the previous stage */
2110 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2112 arg1 = WINED3DTA_CURRENT;
2113 op = WINED3DTOP_SELECTARG1;
2116 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2118 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2119 } else {
2120 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2122 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2123 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2125 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2127 Handled = TRUE; /* Assume will be handled */
2129 /* Other texture operations require special extensions: */
2130 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2132 if (isAlpha) {
2133 opr = GL_SRC_ALPHA;
2134 invopr = GL_ONE_MINUS_SRC_ALPHA;
2135 src3_target = GL_SOURCE3_ALPHA_NV;
2136 opr3_target = GL_OPERAND3_ALPHA_NV;
2137 } else {
2138 opr = GL_SRC_COLOR;
2139 invopr = GL_ONE_MINUS_SRC_COLOR;
2140 src3_target = GL_SOURCE3_RGB_NV;
2141 opr3_target = GL_OPERAND3_RGB_NV;
2143 switch (op) {
2144 case WINED3DTOP_DISABLE: /* Only for alpha */
2145 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2146 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2147 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2148 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2149 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2150 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2151 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2152 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2153 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2154 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2155 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2156 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2157 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2158 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2159 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2160 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2161 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2162 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2163 break;
2164 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
2165 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
2166 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2167 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2168 if (op == WINED3DTOP_SELECTARG1) {
2169 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2170 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2171 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2172 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2173 } else {
2174 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2175 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2176 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2177 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2179 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2180 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2181 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2182 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2183 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2184 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2185 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2186 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2187 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2188 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2189 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2190 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2191 break;
2193 case WINED3DTOP_MODULATE:
2194 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2195 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2196 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2197 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2198 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2199 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2200 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2201 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2202 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2203 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2204 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2205 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2206 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2207 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2208 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2209 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2210 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2211 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2212 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2213 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2214 break;
2215 case WINED3DTOP_MODULATE2X:
2216 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2217 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2218 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2219 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2220 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2221 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2222 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2223 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2224 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2225 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2226 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2227 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2228 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2229 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2230 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2231 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2232 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2233 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2234 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2235 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2236 break;
2237 case WINED3DTOP_MODULATE4X:
2238 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2239 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2240 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2241 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2242 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2243 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2244 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2245 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2246 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2247 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2248 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2249 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2250 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2251 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2252 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2253 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2254 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2255 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2256 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2257 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2258 break;
2260 case WINED3DTOP_ADD:
2261 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2262 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2263 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2264 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2265 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2266 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2267 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2268 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2269 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2270 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2271 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2272 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2273 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2274 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2275 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2276 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2277 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2278 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2279 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2280 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2281 break;
2283 case WINED3DTOP_ADDSIGNED:
2284 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2285 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2286 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2287 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2288 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2289 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2290 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2291 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2292 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2293 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2294 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2295 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2296 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2297 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2298 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2299 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2300 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2301 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2302 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2303 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2304 break;
2306 case WINED3DTOP_ADDSIGNED2X:
2307 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2308 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2309 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2310 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2311 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2312 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2313 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2314 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2315 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2316 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2317 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2318 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2319 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2320 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2321 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2322 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2323 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2324 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2325 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2326 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2327 break;
2329 case WINED3DTOP_ADDSMOOTH:
2330 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2331 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2332 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2333 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2334 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2335 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2336 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2337 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2338 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2339 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2340 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2341 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2342 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2343 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2344 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2345 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2346 switch (opr1) {
2347 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2348 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2349 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2350 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2352 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2353 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2354 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2355 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2356 break;
2358 case WINED3DTOP_BLENDDIFFUSEALPHA:
2359 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2360 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2361 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2362 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2363 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2364 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2365 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
2366 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
2367 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2368 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2369 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2370 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2371 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2372 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2373 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
2374 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
2375 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2376 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2377 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2378 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2379 break;
2380 case WINED3DTOP_BLENDTEXTUREALPHA:
2381 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2382 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2383 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2384 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2385 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2386 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2387 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2388 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2389 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2390 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2391 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2392 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2393 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2394 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2395 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2396 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2397 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2398 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2399 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2400 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2401 break;
2402 case WINED3DTOP_BLENDFACTORALPHA:
2403 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2404 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2405 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2406 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2407 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2408 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2409 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
2410 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
2411 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2412 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2413 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2414 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2415 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2416 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2417 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
2418 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
2419 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2420 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2421 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2422 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2423 break;
2424 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2425 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2426 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2427 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2428 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2429 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2430 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2431 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2432 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2433 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2434 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2435 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2436 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2437 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2438 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2439 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2440 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2441 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2442 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2443 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2444 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2445 break;
2446 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2447 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2448 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2449 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2450 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2451 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2452 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2453 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2454 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2455 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2456 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2457 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2458 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2459 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2460 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2461 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2462 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2463 switch (opr) {
2464 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2465 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2467 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2468 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2469 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2470 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2471 break;
2472 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2473 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2474 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2475 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2476 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2477 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2478 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2479 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2480 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2481 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2482 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2483 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2484 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2485 switch (opr1) {
2486 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2487 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2489 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2490 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2491 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2492 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2493 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2494 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2495 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2496 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2497 break;
2498 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2499 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2500 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2501 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2502 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2503 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2504 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2505 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2506 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2507 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2508 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2509 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2510 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2511 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2512 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2513 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2514 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2515 switch (opr1) {
2516 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2517 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2518 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2519 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2521 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2522 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2523 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2524 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2525 break;
2526 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2527 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2528 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2529 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2530 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2531 switch (opr1) {
2532 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2533 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2534 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2535 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2537 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2538 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2539 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2540 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2541 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2542 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2543 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2544 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2545 switch (opr1) {
2546 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2547 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2549 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2550 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2551 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2552 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2553 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2554 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2555 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2556 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2557 break;
2558 case WINED3DTOP_MULTIPLYADD:
2559 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2560 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2561 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2562 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2563 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2564 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2565 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2566 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2567 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2568 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2569 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2570 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2571 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2572 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2573 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2574 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2575 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2576 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2577 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2578 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2579 break;
2581 case WINED3DTOP_BUMPENVMAP:
2585 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2586 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2588 default:
2589 Handled = FALSE;
2591 if (Handled) {
2592 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2593 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2595 return;
2597 } /* GL_NV_texture_env_combine4 */
2599 Handled = TRUE; /* Again, assume handled */
2600 switch (op) {
2601 case WINED3DTOP_DISABLE: /* Only for alpha */
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, GL_PREVIOUS_EXT);
2605 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2606 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2607 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2608 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2609 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2610 break;
2611 case WINED3DTOP_SELECTARG1:
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, src1);
2615 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2616 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2617 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2618 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2619 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2620 break;
2621 case WINED3DTOP_SELECTARG2:
2622 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2623 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2624 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2625 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2626 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2627 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2628 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2629 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2630 break;
2631 case WINED3DTOP_MODULATE:
2632 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2633 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2634 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2635 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2636 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2637 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2638 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2639 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2640 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2641 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2642 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2643 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2644 break;
2645 case WINED3DTOP_MODULATE2X:
2646 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2647 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2648 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2649 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2650 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2651 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2652 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2653 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2654 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2655 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2656 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2657 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2658 break;
2659 case WINED3DTOP_MODULATE4X:
2660 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2661 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2662 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2663 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2664 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2665 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2666 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2667 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2668 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2669 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2670 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2671 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2672 break;
2673 case WINED3DTOP_ADD:
2674 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2675 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2676 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2677 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2678 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2679 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2680 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2681 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2682 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2683 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2684 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2685 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2686 break;
2687 case WINED3DTOP_ADDSIGNED:
2688 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2689 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2690 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2691 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2692 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2693 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2694 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2695 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2696 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2697 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2698 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2699 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2700 break;
2701 case WINED3DTOP_ADDSIGNED2X:
2702 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2703 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2704 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2705 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2706 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2707 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2708 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2709 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2710 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2711 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2712 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2713 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2714 break;
2715 case WINED3DTOP_SUBTRACT:
2716 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2718 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2719 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2720 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2721 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2722 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2723 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2724 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2725 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2726 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2727 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2728 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2729 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2730 } else {
2731 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2733 break;
2735 case WINED3DTOP_BLENDDIFFUSEALPHA:
2736 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2737 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2738 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2739 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2740 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2741 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2742 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2743 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2744 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2745 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2746 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2747 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2748 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2749 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2750 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2751 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2752 break;
2753 case WINED3DTOP_BLENDTEXTUREALPHA:
2754 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2755 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2756 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2757 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2758 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2759 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2760 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2761 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2762 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2763 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2764 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2765 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2766 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2767 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2768 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2769 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2770 break;
2771 case WINED3DTOP_BLENDFACTORALPHA:
2772 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2773 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2774 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2775 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2776 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2777 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2778 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2779 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2780 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2781 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2782 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2783 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2784 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2785 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2786 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2787 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2788 break;
2789 case WINED3DTOP_BLENDCURRENTALPHA:
2790 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2791 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2792 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2793 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2794 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2795 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2796 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2797 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2798 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2799 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2800 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2801 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2802 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2803 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2804 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2805 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2806 break;
2807 case WINED3DTOP_DOTPRODUCT3:
2808 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2810 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2811 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2813 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2815 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2816 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2817 } else {
2818 FIXME("This version of opengl does not support GL_DOT3\n");
2820 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2821 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2822 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2823 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2824 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2825 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2826 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2827 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2828 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2829 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2830 break;
2831 case WINED3DTOP_LERP:
2832 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2833 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2834 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2835 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2836 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2837 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2838 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2839 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2840 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2841 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2842 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2843 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2844 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2845 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2846 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2847 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2848 break;
2849 case WINED3DTOP_ADDSMOOTH:
2850 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2852 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2853 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2854 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2855 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2856 switch (opr1) {
2857 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2858 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2859 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2860 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2862 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2863 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2864 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2865 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2866 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2867 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2868 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2869 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2870 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2871 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2872 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2873 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2874 } else
2875 Handled = FALSE;
2876 break;
2877 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2878 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2880 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2881 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2882 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2883 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2884 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2885 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2886 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2887 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2888 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2889 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2890 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2891 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2892 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2893 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2894 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2895 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2896 } else
2897 Handled = FALSE;
2898 break;
2899 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2900 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2902 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2903 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2904 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2905 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2906 switch (opr1) {
2907 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2908 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2909 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2910 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2912 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2913 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2914 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2915 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2916 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2917 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2918 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2919 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2920 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2921 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2922 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2923 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2924 } else
2925 Handled = FALSE;
2926 break;
2927 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2928 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2930 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2931 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2932 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2933 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2934 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2935 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2936 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2937 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2938 switch (opr1) {
2939 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2940 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2941 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2942 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2944 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2945 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2946 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2947 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2948 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2949 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2950 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2951 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2952 } else
2953 Handled = FALSE;
2954 break;
2955 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2956 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2958 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2959 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2960 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2961 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2962 switch (opr1) {
2963 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2964 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2965 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2966 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2968 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2969 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2970 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2971 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2972 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2973 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2974 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2975 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2976 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2977 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2978 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2979 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2980 } else
2981 Handled = FALSE;
2982 break;
2983 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2984 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2986 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2987 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2988 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2989 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2990 switch (opr1) {
2991 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2992 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2993 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2994 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2996 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2997 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2998 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2999 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3000 switch (opr1) {
3001 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3002 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3003 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3004 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3006 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
3007 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
3008 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3009 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3010 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3011 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3012 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3013 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3014 } else
3015 Handled = FALSE;
3016 break;
3017 case WINED3DTOP_MULTIPLYADD:
3018 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3020 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3021 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3022 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3023 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3024 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3025 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3026 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3027 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3028 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3029 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3030 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3031 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3032 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3033 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3034 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3035 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3036 } else
3037 Handled = FALSE;
3038 break;
3039 case WINED3DTOP_BUMPENVMAPLUMINANCE:
3040 case WINED3DTOP_BUMPENVMAP:
3041 if (gl_info->supported[NV_TEXTURE_SHADER2])
3043 /* Technically texture shader support without register combiners is possible, but not expected to occur
3044 * on real world cards, so for now a fixme should be enough
3046 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3048 default:
3049 Handled = FALSE;
3052 if (Handled) {
3053 BOOL combineOK = TRUE;
3054 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3056 DWORD op2;
3058 if (isAlpha)
3059 op2 = state->texture_states[Stage][WINED3DTSS_COLOROP];
3060 else
3061 op2 = state->texture_states[Stage][WINED3DTSS_ALPHAOP];
3063 /* Note: If COMBINE4 in effect can't go back to combine! */
3064 switch (op2) {
3065 case WINED3DTOP_ADDSMOOTH:
3066 case WINED3DTOP_BLENDTEXTUREALPHAPM:
3067 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
3068 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
3069 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
3070 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
3071 case WINED3DTOP_MULTIPLYADD:
3072 /* Ignore those implemented in both cases */
3073 switch (op) {
3074 case WINED3DTOP_SELECTARG1:
3075 case WINED3DTOP_SELECTARG2:
3076 combineOK = FALSE;
3077 Handled = FALSE;
3078 break;
3079 default:
3080 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3081 return;
3086 if (combineOK) {
3087 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
3088 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
3090 return;
3094 /* After all the extensions, if still unhandled, report fixme */
3095 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3099 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3101 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3102 BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage);
3103 DWORD mapped_stage = stateblock->device->texUnitMap[stage];
3104 const struct wined3d_gl_info *gl_info = context->gl_info;
3106 TRACE("Setting color op for stage %d\n", stage);
3108 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3109 if (use_ps(stateblock)) return;
3111 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3113 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3115 if (tex_used && mapped_stage >= gl_info->limits.textures)
3117 FIXME("Attempt to enable unsupported stage!\n");
3118 return;
3120 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3121 checkGLcall("glActiveTextureARB");
3124 if (stage >= stateblock->state.lowest_disabled_stage)
3126 TRACE("Stage disabled\n");
3127 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3129 /* Disable everything here */
3130 glDisable(GL_TEXTURE_2D);
3131 checkGLcall("glDisable(GL_TEXTURE_2D)");
3132 glDisable(GL_TEXTURE_3D);
3133 checkGLcall("glDisable(GL_TEXTURE_3D)");
3134 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3136 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3137 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3139 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3141 glDisable(GL_TEXTURE_RECTANGLE_ARB);
3142 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3145 /* All done */
3146 return;
3149 /* The sampler will also activate the correct texture dimensions, so no
3150 * need to do it here if the sampler for this stage is dirty. */
3151 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3152 texture_activate_dimensions(stateblock->state.textures[stage], gl_info);
3154 set_tex_op(gl_info, &stateblock->state, FALSE, stage,
3155 stateblock->state.texture_states[stage][WINED3DTSS_COLOROP],
3156 stateblock->state.texture_states[stage][WINED3DTSS_COLORARG1],
3157 stateblock->state.texture_states[stage][WINED3DTSS_COLORARG2],
3158 stateblock->state.texture_states[stage][WINED3DTSS_COLORARG0]);
3161 void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3163 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3164 BOOL tex_used = stateblock->device->fixed_function_usage_map & (1 << stage);
3165 DWORD mapped_stage = stateblock->device->texUnitMap[stage];
3166 const struct wined3d_gl_info *gl_info = context->gl_info;
3167 DWORD op, arg1, arg2, arg0;
3169 TRACE("Setting alpha op for stage %d\n", stage);
3170 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3171 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3173 if (tex_used && mapped_stage >= gl_info->limits.textures)
3175 FIXME("Attempt to enable unsupported stage!\n");
3176 return;
3178 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3179 checkGLcall("glActiveTextureARB");
3182 op = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAOP];
3183 arg1 = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAARG1];
3184 arg2 = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAARG2];
3185 arg0 = stateblock->state.texture_states[stage][WINED3DTSS_ALPHAARG0];
3187 if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && !stage && stateblock->state.textures[0])
3189 IWineD3DBaseTextureImpl *texture = stateblock->state.textures[0];
3190 GLenum texture_dimensions = texture->baseTexture.target;
3192 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3194 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *)texture->baseTexture.sub_resources[0];
3196 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3198 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3199 * properly. On the other hand applications can still use texture combiners apparently. This code
3200 * takes care that apps cannot remove the texture's alpha channel entirely.
3202 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3203 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3204 * and alpha component of diffuse color to draw things like translucent text and perform other
3205 * blending effects.
3207 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3208 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3209 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3210 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3211 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3212 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3213 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3214 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3215 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3216 * alpha.
3218 * What to do with multitexturing? So far no app has been found that uses color keying with
3219 * multitexturing */
3220 if (op == WINED3DTOP_DISABLE)
3222 arg1 = WINED3DTA_TEXTURE;
3223 op = WINED3DTOP_SELECTARG1;
3225 else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE)
3227 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
3229 arg2 = WINED3DTA_TEXTURE;
3230 op = WINED3DTOP_MODULATE;
3232 else arg1 = WINED3DTA_TEXTURE;
3234 else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE)
3236 if (stateblock->state.render_states[WINED3DRS_ALPHABLENDENABLE])
3238 arg1 = WINED3DTA_TEXTURE;
3239 op = WINED3DTOP_MODULATE;
3241 else arg2 = WINED3DTA_TEXTURE;
3247 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3248 * this if block here, and the other code(color keying, texture unit selection) are the same
3250 TRACE("Setting alpha op for stage %d\n", stage);
3251 if (gl_info->supported[NV_REGISTER_COMBINERS])
3253 set_tex_op_nvrc(gl_info, &stateblock->state, TRUE, stage, op, arg1, arg2, arg0,
3254 mapped_stage, stateblock->state.texture_states[stage][WINED3DTSS_RESULTARG]);
3256 else
3258 set_tex_op(gl_info, &stateblock->state, TRUE, stage, op, arg1, arg2, arg0);
3262 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3264 DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3265 DWORD mapped_stage = stateblock->device->texUnitMap[texUnit];
3266 const struct wined3d_gl_info *gl_info = context->gl_info;
3267 BOOL generated;
3268 int coordIdx;
3270 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3271 if (use_vs(stateblock) || isStateDirty(context, STATE_VDECL))
3273 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3274 return;
3277 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3278 if (mapped_stage >= gl_info->limits.textures) return;
3280 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3281 checkGLcall("glActiveTextureARB");
3282 generated = (stateblock->state.texture_states[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xffff0000)
3283 != WINED3DTSS_TCI_PASSTHRU;
3284 coordIdx = min(stateblock->state.texture_states[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000ffff], MAX_TEXTURES - 1);
3286 set_texture_matrix(&stateblock->state.transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
3287 stateblock->state.texture_states[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
3288 generated, context->last_was_rhw,
3289 stateblock->device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3290 ? stateblock->device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3291 : WINED3DFMT_UNKNOWN,
3292 stateblock->device->frag_pipe->ffp_proj_control);
3294 /* The sampler applying function calls us if this changes */
3295 if ((context->lastWasPow2Texture & (1 << texUnit)) && stateblock->state.textures[texUnit])
3297 if(generated) {
3298 FIXME("Non-power2 texture being used with generated texture coords\n");
3300 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3301 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3302 if (!use_ps(stateblock)) {
3303 TRACE("Non power two matrix multiply fixup\n");
3304 glMultMatrixf(stateblock->state.textures[texUnit]->baseTexture.pow2Matrix);
3309 static void unloadTexCoords(const struct wined3d_gl_info *gl_info)
3311 unsigned int texture_idx;
3313 for (texture_idx = 0; texture_idx < gl_info->limits.texture_stages; ++texture_idx)
3315 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3316 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3320 static void loadTexCoords(const struct wined3d_gl_info *gl_info, IWineD3DStateBlockImpl *stateblock,
3321 const struct wined3d_stream_info *si, GLuint *curVBO)
3323 unsigned int mapped_stage = 0;
3324 unsigned int textureNo = 0;
3326 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3328 int coordIdx = stateblock->state.texture_states[textureNo][WINED3DTSS_TEXCOORDINDEX];
3330 mapped_stage = stateblock->device->texUnitMap[textureNo];
3331 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3333 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3335 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3336 const struct wined3d_stream_state *stream = &stateblock->state.streams[e->stream_idx];
3338 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
3339 textureNo, mapped_stage, coordIdx, e->data);
3341 if (*curVBO != e->buffer_object)
3343 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
3344 checkGLcall("glBindBufferARB");
3345 *curVBO = e->buffer_object;
3348 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3349 checkGLcall("glClientActiveTextureARB");
3351 /* The coords to supply depend completely on the fvf / vertex shader */
3352 glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3353 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
3354 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3355 } else {
3356 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3359 if (gl_info->supported[NV_REGISTER_COMBINERS])
3361 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3362 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3364 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3368 checkGLcall("loadTexCoords");
3371 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3373 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3374 DWORD mapped_stage = stateblock->device->texUnitMap[stage];
3375 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3376 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3377 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3378 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3379 const struct wined3d_gl_info *gl_info = context->gl_info;
3381 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3383 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3384 return;
3387 if (mapped_stage >= gl_info->limits.fragment_samplers)
3389 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3390 return;
3392 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3393 checkGLcall("glActiveTextureARB");
3395 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3397 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3398 * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
3399 * means use the vertex position (camera-space) as the input texture coordinates
3400 * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
3401 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3402 * to the TEXCOORDINDEX value
3404 switch (stateblock->state.texture_states[stage][WINED3DTSS_TEXCOORDINDEX] & 0xffff0000)
3406 case WINED3DTSS_TCI_PASSTHRU:
3407 /* Use the specified texture coordinates contained within the
3408 * vertex format. This value resolves to zero. */
3409 glDisable(GL_TEXTURE_GEN_S);
3410 glDisable(GL_TEXTURE_GEN_T);
3411 glDisable(GL_TEXTURE_GEN_R);
3412 glDisable(GL_TEXTURE_GEN_Q);
3413 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3414 break;
3416 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3417 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3418 * as the input texture coordinates for this stage's texture transformation. This
3419 * equates roughly to EYE_LINEAR */
3421 glMatrixMode(GL_MODELVIEW);
3422 glPushMatrix();
3423 glLoadIdentity();
3424 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3425 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3426 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3427 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3428 glPopMatrix();
3429 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3431 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3432 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3433 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3434 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3436 glEnable(GL_TEXTURE_GEN_S);
3437 glEnable(GL_TEXTURE_GEN_T);
3438 glEnable(GL_TEXTURE_GEN_R);
3439 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3441 break;
3443 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3444 /* Note that NV_TEXGEN_REFLECTION support is implied when
3445 * ARB_TEXTURE_CUBE_MAP is supported */
3446 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3448 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3449 break;
3452 glMatrixMode(GL_MODELVIEW);
3453 glPushMatrix();
3454 glLoadIdentity();
3455 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3456 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3457 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3458 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3459 glPopMatrix();
3460 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3462 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3463 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3464 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3465 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3467 glEnable(GL_TEXTURE_GEN_S);
3468 glEnable(GL_TEXTURE_GEN_T);
3469 glEnable(GL_TEXTURE_GEN_R);
3470 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3472 break;
3474 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3475 /* Note that NV_TEXGEN_REFLECTION support is implied when
3476 * ARB_TEXTURE_CUBE_MAP is supported */
3477 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3479 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3480 break;
3483 glMatrixMode(GL_MODELVIEW);
3484 glPushMatrix();
3485 glLoadIdentity();
3486 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3487 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3488 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3489 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3490 glPopMatrix();
3491 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3493 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3494 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3495 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3496 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3498 glEnable(GL_TEXTURE_GEN_S);
3499 glEnable(GL_TEXTURE_GEN_T);
3500 glEnable(GL_TEXTURE_GEN_R);
3501 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3503 break;
3505 case WINED3DTSS_TCI_SPHEREMAP:
3506 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3507 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3508 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3510 glEnable(GL_TEXTURE_GEN_S);
3511 glEnable(GL_TEXTURE_GEN_T);
3512 glDisable(GL_TEXTURE_GEN_R);
3513 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3515 break;
3517 default:
3518 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %#x.\n",
3519 stateblock->state.texture_states[stage][WINED3DTSS_TEXCOORDINDEX]);
3520 glDisable(GL_TEXTURE_GEN_S);
3521 glDisable(GL_TEXTURE_GEN_T);
3522 glDisable(GL_TEXTURE_GEN_R);
3523 glDisable(GL_TEXTURE_GEN_Q);
3524 checkGLcall("Disable texgen.");
3526 break;
3529 /* Update the texture matrix */
3530 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
3531 transform_texture(STATE_TEXTURESTAGE(stage, WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
3534 if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
3535 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3536 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3537 * and do all the things linked to it
3538 * TODO: Tidy that up to reload only the arrays of the changed unit
3540 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3542 unloadTexCoords(gl_info);
3543 loadTexCoords(gl_info, stateblock, &stateblock->device->strided_streams, &curVBO);
3547 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3549 IWineD3DDeviceImpl *device = stateblock->device;
3551 /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
3552 * has an update pending
3554 if(isStateDirty(context, STATE_VDECL) ||
3555 isStateDirty(context, STATE_PIXELSHADER)) {
3556 return;
3559 device->shader_backend->shader_load_constants(context, use_ps(stateblock), use_vs(stateblock));
3562 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3564 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3565 IWineD3DPixelShaderImpl *ps = stateblock->state.pixel_shader;
3567 if (ps && stage && (ps->baseShader.reg_maps.luminanceparams & (1 << stage)))
3569 /* The pixel shader has to know the luminance scale. Do a constants update if it
3570 * isn't scheduled anyway
3572 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3573 !isStateDirty(context, STATE_PIXELSHADER)) {
3574 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3579 static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3581 const DWORD sampler = state - STATE_SAMPLER(0);
3582 IWineD3DBaseTextureImpl *texture = stateblock->state.textures[sampler];
3584 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
3586 if(!texture) return;
3587 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3588 * basetexture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3589 * scaling is reapplied or removed, the texture matrix has to be reapplied
3591 * The mapped stage is already active because the sampler() function below, which is part of the
3592 * misc pipeline
3594 if(sampler < MAX_TEXTURES) {
3595 const BOOL texIsPow2 = !texture->baseTexture.pow2Matrix_identity;
3597 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3599 if (texIsPow2) context->lastWasPow2Texture |= 1 << sampler;
3600 else context->lastWasPow2Texture &= ~(1 << sampler);
3601 transform_texture(STATE_TEXTURESTAGE(stateblock->device->texUnitMap[sampler],
3602 WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
3607 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3609 DWORD sampler = state - STATE_SAMPLER(0);
3610 DWORD mapped_stage = stateblock->device->texUnitMap[sampler];
3611 const struct wined3d_gl_info *gl_info = context->gl_info;
3612 union {
3613 float f;
3614 DWORD d;
3615 } tmpvalue;
3617 TRACE("Sampler: %d\n", sampler);
3618 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3619 * only has to bind textures and set the per texture states
3622 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3624 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3625 return;
3628 if (mapped_stage >= gl_info->limits.combined_samplers)
3630 return;
3632 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3633 checkGLcall("glActiveTextureARB");
3635 if (stateblock->state.textures[sampler])
3637 IWineD3DBaseTexture *texture = (IWineD3DBaseTexture *)stateblock->state.textures[sampler];
3638 BOOL srgb = stateblock->state.sampler_states[sampler][WINED3DSAMP_SRGBTEXTURE];
3640 IWineD3DBaseTexture_BindTexture(texture, srgb);
3641 basetexture_apply_state_changes(texture,
3642 stateblock->state.texture_states[sampler],
3643 stateblock->state.sampler_states[sampler], gl_info);
3645 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3647 tmpvalue.d = stateblock->state.sampler_states[sampler][WINED3DSAMP_MIPMAPLODBIAS];
3648 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3649 GL_TEXTURE_LOD_BIAS_EXT,
3650 tmpvalue.f);
3651 checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3654 if (!use_ps(stateblock) && sampler < stateblock->state.lowest_disabled_stage)
3656 if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && !sampler)
3658 /* If color keying is enabled update the alpha test, it depends on the existence
3659 * of a color key in stage 0
3661 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3665 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3666 if (!stateblock->state.textures[sampler]->baseTexture.pow2Matrix_identity)
3668 IWineD3DDeviceImpl *d3ddevice = stateblock->device;
3669 d3ddevice->shader_backend->shader_load_np2fixup_constants(
3670 (IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock));
3673 else if (mapped_stage < gl_info->limits.textures)
3675 if (sampler < stateblock->state.lowest_disabled_stage)
3677 /* TODO: What should I do with pixel shaders here ??? */
3678 if (stateblock->state.render_states[WINED3DRS_COLORKEYENABLE] && !sampler)
3680 /* If color keying is enabled update the alpha test, it depends on the existence
3681 * of a color key in stage 0
3683 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3685 } /* Otherwise tex_colorop disables the stage */
3686 glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler]);
3687 checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->device->dummyTextureName[sampler])");
3691 void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3693 IWineD3DDeviceImpl *device = stateblock->device;
3694 BOOL use_pshader = use_ps(stateblock);
3695 BOOL use_vshader = use_vs(stateblock);
3696 unsigned int i;
3698 if (use_pshader) {
3699 if(!context->last_was_pshader) {
3700 /* Former draw without a pixel shader, some samplers
3701 * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
3702 * make sure to enable them
3704 for(i=0; i < MAX_FRAGMENT_SAMPLERS; i++) {
3705 if(!isStateDirty(context, STATE_SAMPLER(i))) {
3706 sampler(STATE_SAMPLER(i), stateblock, context);
3709 context->last_was_pshader = TRUE;
3710 } else {
3711 /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
3712 * if a different texture was bound. I don't have to do anything.
3715 } else {
3716 /* Disabled the pixel shader - color ops weren't applied
3717 * while it was enabled, so re-apply them. */
3718 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3720 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)))
3721 stateblock_apply_state(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
3723 context->last_was_pshader = FALSE;
3726 if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
3727 device->shader_backend->shader_select(context, use_pshader, use_vshader);
3729 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
3730 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
3735 static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3737 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3738 IWineD3DPixelShaderImpl *ps = stateblock->state.pixel_shader;
3740 if (ps && stage && (ps->baseShader.reg_maps.bumpmat & (1 << stage)))
3742 /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
3743 * anyway
3745 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3746 !isStateDirty(context, STATE_PIXELSHADER)) {
3747 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3752 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3754 /* This function is called by transform_view below if the view matrix was changed too
3756 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3757 * does not always update the world matrix, only on a switch between transformed
3758 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3759 * draw, but that should be rather rare and cheaper in total.
3761 glMatrixMode(GL_MODELVIEW);
3762 checkGLcall("glMatrixMode");
3764 if(context->last_was_rhw) {
3765 glLoadIdentity();
3766 checkGLcall("glLoadIdentity()");
3767 } else {
3768 /* In the general case, the view matrix is the identity matrix */
3769 if (stateblock->device->view_ident)
3771 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3772 checkGLcall("glLoadMatrixf");
3774 else
3776 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
3777 checkGLcall("glLoadMatrixf");
3778 glMultMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3779 checkGLcall("glMultMatrixf");
3784 static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3786 UINT index = state - STATE_CLIPPLANE(0);
3788 if (isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= context->gl_info->limits.clipplanes)
3790 return;
3793 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3794 if(!use_vs(stateblock)) {
3795 glMatrixMode(GL_MODELVIEW);
3796 glPushMatrix();
3797 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
3799 else
3801 /* with vertex shaders, clip planes are not transformed in direct3d,
3802 * in OpenGL they are still transformed by the model view.
3803 * Use this to swap the y coordinate if necessary
3805 glMatrixMode(GL_MODELVIEW);
3806 glPushMatrix();
3807 glLoadIdentity();
3808 if (context->render_offscreen) glScalef(1.0f, -1.0f, 1.0f);
3811 TRACE("Clipplane [%f,%f,%f,%f]\n",
3812 stateblock->state.clip_planes[index][0],
3813 stateblock->state.clip_planes[index][1],
3814 stateblock->state.clip_planes[index][2],
3815 stateblock->state.clip_planes[index][3]);
3816 glClipPlane(GL_CLIP_PLANE0 + index, stateblock->state.clip_planes[index]);
3817 checkGLcall("glClipPlane");
3819 glPopMatrix();
3822 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3824 UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
3825 GLenum glMat;
3826 TRACE("Setting world matrix %d\n", matrix);
3828 if (matrix >= context->gl_info->limits.blends)
3830 WARN("Unsupported blend matrix set\n");
3831 return;
3832 } else if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
3833 return;
3836 /* GL_MODELVIEW0_ARB: 0x1700
3837 * GL_MODELVIEW1_ARB: 0x850a
3838 * GL_MODELVIEW2_ARB: 0x8722
3839 * GL_MODELVIEW3_ARB: 0x8723
3840 * etc
3841 * GL_MODELVIEW31_ARB: 0x873F
3843 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3844 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3846 glMatrixMode(glMat);
3847 checkGLcall("glMatrixMode(glMat)");
3849 /* World matrix 0 is multiplied with the view matrix because d3d uses 3 matrices while gl uses only 2. To avoid
3850 * weighting the view matrix incorrectly it has to be multiplied into every gl modelview matrix
3852 if (stateblock->device->view_ident)
3854 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3855 checkGLcall("glLoadMatrixf");
3857 else
3859 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
3860 checkGLcall("glLoadMatrixf");
3861 glMultMatrixf(&stateblock->state.transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3862 checkGLcall("glMultMatrixf");
3866 static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3868 WINED3DVERTEXBLENDFLAGS f = stateblock->state.render_states[WINED3DRS_VERTEXBLEND];
3869 static unsigned int once;
3871 if (f == WINED3DVBF_DISABLE) return;
3873 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3874 else WARN("Vertex blend flags %#x not supported.\n", f);
3877 static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3879 WINED3DVERTEXBLENDFLAGS val = stateblock->state.render_states[WINED3DRS_VERTEXBLEND];
3880 const struct wined3d_gl_info *gl_info = context->gl_info;
3881 static unsigned int once;
3883 switch(val) {
3884 case WINED3DVBF_1WEIGHTS:
3885 case WINED3DVBF_2WEIGHTS:
3886 case WINED3DVBF_3WEIGHTS:
3887 glEnable(GL_VERTEX_BLEND_ARB);
3888 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3890 /* D3D adds one more matrix which has weight (1 - sum(weights)). This is enabled at context
3891 * creation with enabling GL_WEIGHT_SUM_UNITY_ARB.
3893 GL_EXTCALL(glVertexBlendARB(stateblock->state.render_states[WINED3DRS_VERTEXBLEND] + 1));
3895 if (!stateblock->device->vertexBlendUsed)
3897 unsigned int i;
3898 for (i = 1; i < gl_info->limits.blends; ++i)
3900 if (!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i))))
3902 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)), stateblock, context);
3905 stateblock->device->vertexBlendUsed = TRUE;
3907 break;
3909 case WINED3DVBF_TWEENING:
3910 case WINED3DVBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3911 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3912 else WARN("Vertex blend flags %#x not supported.\n", val);
3913 /* Fall through. */
3914 case WINED3DVBF_DISABLE:
3915 glDisable(GL_VERTEX_BLEND_ARB);
3916 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3917 break;
3921 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3923 const struct wined3d_gl_info *gl_info = context->gl_info;
3924 const struct wined3d_light_info *light = NULL;
3925 unsigned int k;
3927 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3928 * NOTE: We have to reset the positions even if the light/plane is not currently
3929 * enabled, since the call to enable it will not reset the position.
3930 * NOTE2: Apparently texture transforms do NOT need reapplying
3933 glMatrixMode(GL_MODELVIEW);
3934 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3935 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
3936 checkGLcall("glLoadMatrixf(...)");
3938 /* Reset lights. TODO: Call light apply func */
3939 for (k = 0; k < stateblock->device->maxConcurrentLights; ++k)
3941 light = stateblock->state.lights[k];
3942 if(!light) continue;
3943 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3944 checkGLcall("glLightfv posn");
3945 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3946 checkGLcall("glLightfv dirn");
3949 /* Reset Clipping Planes */
3950 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3952 if(!isStateDirty(context, STATE_CLIPPLANE(k))) {
3953 clipplane(STATE_CLIPPLANE(k), stateblock, context);
3957 if(context->last_was_rhw) {
3958 glLoadIdentity();
3959 checkGLcall("glLoadIdentity()");
3960 /* No need to update the world matrix, the identity is fine */
3961 return;
3964 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3965 * No need to do it here if the state is scheduled for update.
3967 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
3968 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
3971 /* Avoid looping over a number of matrices if the app never used the functionality */
3972 if (stateblock->device->vertexBlendUsed)
3974 for (k = 1; k < gl_info->limits.blends; ++k)
3976 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)))) {
3977 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)), stateblock, context);
3983 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3985 glMatrixMode(GL_PROJECTION);
3986 checkGLcall("glMatrixMode(GL_PROJECTION)");
3987 glLoadIdentity();
3988 checkGLcall("glLoadIdentity");
3990 if (context->last_was_rhw)
3992 double x = stateblock->state.viewport.X;
3993 double y = stateblock->state.viewport.Y;
3994 double w = stateblock->state.viewport.Width;
3995 double h = stateblock->state.viewport.Height;
3997 TRACE("Calling glOrtho with x %.8e, y %.8e, w %.8e, h %.8e.\n", x, y, w, h);
3998 if (context->render_offscreen)
3999 glOrtho(x, x + w, -y, -y - h, 0.0, -1.0);
4000 else
4001 glOrtho(x, x + w, y + h, y, 0.0, -1.0);
4002 checkGLcall("glOrtho");
4004 /* D3D texture coordinates are flipped compared to OpenGL ones, so
4005 * render everything upside down when rendering offscreen. */
4006 if (context->render_offscreen)
4008 glScalef(1.0f, -1.0f, 1.0f);
4009 checkGLcall("glScalef");
4012 /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
4013 glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f);
4014 checkGLcall("glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f)");
4016 else
4018 /* The rule is that the window coordinate 0 does not correspond to the
4019 beginning of the first pixel, but the center of the first pixel.
4020 As a consequence if you want to correctly draw one line exactly from
4021 the left to the right end of the viewport (with all matrices set to
4022 be identity), the x coords of both ends of the line would be not
4023 -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
4024 instead.
4026 1.0 / Width is used because the coord range goes from -1.0 to 1.0, then we
4027 divide by the Width/Height, so we need the half range(1.0) to translate by
4028 half a pixel.
4030 The other fun is that d3d's output z range after the transformation is [0;1],
4031 but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl
4032 scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot
4033 of Z buffer precision and the clear values do not match in the z test. Thus scale
4034 [0;1] to [-1;1], so when gl undoes that we utilize the full z range
4038 * Careful with the order of operations here, we're essentially working backwards:
4039 * x = x + 1/w;
4040 * y = (y - 1/h) * flip;
4041 * z = z * 2 - 1;
4043 * Becomes:
4044 * glTranslatef(0.0, 0.0, -1.0);
4045 * glScalef(1.0, 1.0, 2.0);
4047 * glScalef(1.0, flip, 1.0);
4048 * glTranslatef(1/w, -1/h, 0.0);
4050 * This is equivalent to:
4051 * glTranslatef(1/w, -flip/h, -1.0)
4052 * glScalef(1.0, flip, 2.0);
4055 /* Translate by slightly less than a half pixel to force a top-left
4056 * filling convention. We want the difference to be large enough that
4057 * it doesn't get lost due to rounding inside the driver, but small
4058 * enough to prevent it from interfering with any anti-aliasing. */
4059 GLfloat xoffset = (63.0f / 64.0f) / stateblock->state.viewport.Width;
4060 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->state.viewport.Height;
4062 if (context->render_offscreen)
4064 /* D3D texture coordinates are flipped compared to OpenGL ones, so
4065 * render everything upside down when rendering offscreen. */
4066 glTranslatef(xoffset, -yoffset, -1.0f);
4067 checkGLcall("glTranslatef(xoffset, -yoffset, -1.0f)");
4068 glScalef(1.0f, -1.0f, 2.0f);
4069 } else {
4070 glTranslatef(xoffset, yoffset, -1.0f);
4071 checkGLcall("glTranslatef(xoffset, yoffset, -1.0f)");
4072 glScalef(1.0f, 1.0f, 2.0f);
4074 checkGLcall("glScalef");
4076 glMultMatrixf(&stateblock->state.transforms[WINED3DTS_PROJECTION].u.m[0][0]);
4077 checkGLcall("glLoadMatrixf");
4081 /* This should match any arrays loaded in loadVertexData.
4082 * TODO: Only load / unload arrays if we have to.
4084 static inline void unloadVertexData(const struct wined3d_gl_info *gl_info)
4086 glDisableClientState(GL_VERTEX_ARRAY);
4087 glDisableClientState(GL_NORMAL_ARRAY);
4088 glDisableClientState(GL_COLOR_ARRAY);
4089 if (gl_info->supported[EXT_SECONDARY_COLOR])
4091 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4093 if (gl_info->supported[ARB_VERTEX_BLEND])
4095 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4097 unloadTexCoords(gl_info);
4100 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4102 const struct wined3d_gl_info *gl_info = context->gl_info;
4104 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4105 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4107 context->numbered_array_mask &= ~(1 << i);
4110 /* This should match any arrays loaded in loadNumberedArrays
4111 * TODO: Only load / unload arrays if we have to.
4113 static inline void unloadNumberedArrays(struct wined3d_context *context)
4115 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4116 GLint maxAttribs = 16;
4117 int i;
4119 /* Leave all the attribs disabled */
4120 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
4121 /* MESA does not support it right not */
4122 if (glGetError() != GL_NO_ERROR)
4123 maxAttribs = 16;
4124 for (i = 0; i < maxAttribs; ++i) {
4125 unload_numbered_array(context, i);
4129 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
4130 const struct wined3d_stream_info *stream_info, struct wined3d_context *context)
4132 const struct wined3d_gl_info *gl_info = context->gl_info;
4133 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4134 int i;
4135 struct wined3d_buffer *vb;
4136 DWORD_PTR shift_index;
4138 /* Default to no instancing */
4139 stateblock->device->instancedDraw = FALSE;
4141 for (i = 0; i < MAX_ATTRIBS; i++)
4143 const struct wined3d_stream_state *stream;
4145 if (!(stream_info->use_map & (1 << i)))
4147 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4148 continue;
4151 stream = &stateblock->state.streams[stream_info->elements[i].stream_idx];
4153 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4154 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4156 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4157 stateblock->device->instancedDraw = TRUE;
4158 continue;
4161 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].buffer_object);
4163 if (stream_info->elements[i].stride)
4165 if (curVBO != stream_info->elements[i].buffer_object)
4167 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].buffer_object));
4168 checkGLcall("glBindBufferARB");
4169 curVBO = stream_info->elements[i].buffer_object;
4171 /* Use the VBO to find out if a vertex buffer exists, not the vb
4172 * pointer. vb can point to a user pointer data blob. In that case
4173 * curVBO will be 0. If there is a vertex buffer but no vbo we
4174 * won't be load converted attributes anyway. */
4175 vb = stream->buffer;
4176 if (curVBO && vb->conversion_shift)
4178 TRACE("Loading attribute from shifted buffer\n");
4179 TRACE("Attrib %d has original stride %d, new stride %d\n",
4180 i, stream_info->elements[i].stride, vb->conversion_stride);
4181 TRACE("Original offset %p, additional offset 0x%08x\n",
4182 stream_info->elements[i].data, vb->conversion_shift[(DWORD_PTR)stream_info->elements[i].data]);
4183 TRACE("Opengl type %#x\n", stream_info->elements[i].format->gl_vtx_type);
4184 shift_index = ((DWORD_PTR)stream_info->elements[i].data + stream->offset);
4185 shift_index = shift_index % stream_info->elements[i].stride;
4186 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4187 stream_info->elements[i].format->gl_vtx_type,
4188 stream_info->elements[i].format->gl_normalized,
4189 vb->conversion_stride, stream_info->elements[i].data + vb->conversion_shift[shift_index]
4190 + stateblock->state.load_base_vertex_index * stream_info->elements[i].stride
4191 + stream->offset));
4193 } else {
4194 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4195 stream_info->elements[i].format->gl_vtx_type,
4196 stream_info->elements[i].format->gl_normalized,
4197 stream_info->elements[i].stride, stream_info->elements[i].data
4198 + stateblock->state.load_base_vertex_index * stream_info->elements[i].stride
4199 + stream->offset));
4202 if (!(context->numbered_array_mask & (1 << i)))
4204 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4205 context->numbered_array_mask |= (1 << i);
4208 else
4210 /* Stride = 0 means always the same values.
4211 * glVertexAttribPointerARB doesn't do that. Instead disable the
4212 * pointer and set up the attribute statically. But we have to
4213 * figure out the system memory address. */
4214 const BYTE *ptr = stream_info->elements[i].data + stream->offset;
4215 if (stream_info->elements[i].buffer_object)
4217 vb = stream->buffer;
4218 ptr += (ULONG_PTR)buffer_get_sysmem(vb, gl_info);
4221 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4223 switch (stream_info->elements[i].format->id)
4225 case WINED3DFMT_R32_FLOAT:
4226 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4227 break;
4228 case WINED3DFMT_R32G32_FLOAT:
4229 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4230 break;
4231 case WINED3DFMT_R32G32B32_FLOAT:
4232 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4233 break;
4234 case WINED3DFMT_R32G32B32A32_FLOAT:
4235 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4236 break;
4238 case WINED3DFMT_R8G8B8A8_UINT:
4239 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4240 break;
4241 case WINED3DFMT_B8G8R8A8_UNORM:
4242 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4244 const DWORD *src = (const DWORD *)ptr;
4245 DWORD c = *src & 0xff00ff00;
4246 c |= (*src & 0xff0000) >> 16;
4247 c |= (*src & 0xff) << 16;
4248 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4249 break;
4251 /* else fallthrough */
4252 case WINED3DFMT_R8G8B8A8_UNORM:
4253 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4254 break;
4256 case WINED3DFMT_R16G16_SINT:
4257 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4258 break;
4259 case WINED3DFMT_R16G16B16A16_SINT:
4260 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4261 break;
4263 case WINED3DFMT_R16G16_SNORM:
4265 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4266 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4267 break;
4269 case WINED3DFMT_R16G16_UNORM:
4271 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4272 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4273 break;
4275 case WINED3DFMT_R16G16B16A16_SNORM:
4276 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4277 break;
4278 case WINED3DFMT_R16G16B16A16_UNORM:
4279 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4280 break;
4282 case WINED3DFMT_R10G10B10A2_UINT:
4283 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4284 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4285 break;
4286 case WINED3DFMT_R10G10B10A2_SNORM:
4287 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4288 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4289 break;
4291 case WINED3DFMT_R16G16_FLOAT:
4292 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4293 * byte float according to the IEEE standard
4295 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4296 break;
4297 case WINED3DFMT_R16G16B16A16_FLOAT:
4298 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4299 break;
4301 default:
4302 ERR("Unexpected declaration in stride 0 attributes\n");
4303 break;
4308 checkGLcall("Loading numbered arrays");
4311 /* Used from 2 different functions, and too big to justify making it inlined */
4312 static void loadVertexData(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
4313 const struct wined3d_stream_info *si)
4315 const struct wined3d_gl_info *gl_info = context->gl_info;
4316 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4317 const struct wined3d_stream_info_element *e;
4318 const struct wined3d_stream_state *stream;
4320 TRACE("Using fast vertex array code\n");
4322 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4323 stateblock->device->instancedDraw = FALSE;
4325 /* Blend Data ---------------------------------------------- */
4326 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4327 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4329 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4330 stream = &stateblock->state.streams[e->stream_idx];
4332 if (gl_info->supported[ARB_VERTEX_BLEND])
4334 TRACE("Blend %u %p %u\n", e->format->component_count,
4335 e->data + stateblock->state.load_base_vertex_index * e->stride, e->stride + stream->offset);
4337 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4338 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4340 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4342 if (curVBO != e->buffer_object)
4344 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4345 checkGLcall("glBindBufferARB");
4346 curVBO = e->buffer_object;
4349 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4350 e->format->gl_vtx_format,
4351 e->format->gl_vtx_type,
4352 e->stride,
4353 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4354 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4355 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset));
4357 checkGLcall("glWeightPointerARB");
4359 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4361 static BOOL warned;
4362 if (!warned)
4364 FIXME("blendMatrixIndices support\n");
4365 warned = TRUE;
4368 } else {
4369 /* TODO: support blends in drawStridedSlow
4370 * No need to write a FIXME here, this is done after the general vertex decl decoding
4372 WARN("unsupported blending in openGl\n");
4375 else
4377 if (gl_info->supported[ARB_VERTEX_BLEND])
4379 static const GLbyte one = 1;
4380 GL_EXTCALL(glWeightbvARB(1, &one));
4381 checkGLcall("glWeightivARB(gl_info->max_blends, weights)");
4385 /* Point Size ----------------------------------------------*/
4386 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4388 /* no such functionality in the fixed function GL pipeline */
4389 TRACE("Cannot change ptSize here in openGl\n");
4390 /* TODO: Implement this function in using shaders if they are available */
4393 /* Vertex Pointers -----------------------------------------*/
4394 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4396 e = &si->elements[WINED3D_FFP_POSITION];
4397 stream = &stateblock->state.streams[e->stream_idx];
4399 if (curVBO != e->buffer_object)
4401 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4402 checkGLcall("glBindBufferARB");
4403 curVBO = e->buffer_object;
4406 /* min(WINED3D_ATR_FORMAT(position),3) to Disable RHW mode as 'w' coord
4407 handling for rhw mode should not impact screen position whereas in GL it does.
4408 This may result in very slightly distorted textures in rhw mode.
4409 There's always the other option of fixing the view matrix to
4410 prevent w from having any effect.
4412 This only applies to user pointer sources, in VBOs the vertices are fixed up
4414 if (!e->buffer_object)
4416 TRACE("glVertexPointer(3, %#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4417 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4418 glVertexPointer(3 /* min(e->format->gl_vtx_format, 3) */, e->format->gl_vtx_type, e->stride,
4419 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4421 else
4423 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4424 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4425 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4426 glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4427 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4429 checkGLcall("glVertexPointer(...)");
4430 glEnableClientState(GL_VERTEX_ARRAY);
4431 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4434 /* Normals -------------------------------------------------*/
4435 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4437 e = &si->elements[WINED3D_FFP_NORMAL];
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("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4448 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4449 glNormalPointer(e->format->gl_vtx_type, e->stride,
4450 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4451 checkGLcall("glNormalPointer(...)");
4452 glEnableClientState(GL_NORMAL_ARRAY);
4453 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4455 } else {
4456 glNormal3f(0, 0, 0);
4457 checkGLcall("glNormal3f(0, 0, 0)");
4460 /* Diffuse Colour --------------------------------------------*/
4461 /* WARNING: Data here MUST be in RGBA format, so cannot */
4462 /* go directly into fast mode from app pgm, because */
4463 /* directx requires data in BGRA format. */
4464 /* currently fixupVertices swizzles the format, but this isn't*/
4465 /* very practical when using VBOs */
4466 /* NOTE: Unless we write a vertex shader to swizzle the colour*/
4467 /* , or the user doesn't care and wants the speed advantage */
4469 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4471 e = &si->elements[WINED3D_FFP_DIFFUSE];
4472 stream = &stateblock->state.streams[e->stream_idx];
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 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4482 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4483 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4484 glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4485 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4486 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4487 glEnableClientState(GL_COLOR_ARRAY);
4488 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4490 } else {
4491 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4492 checkGLcall("glColor4f(1, 1, 1, 1)");
4495 /* Specular Colour ------------------------------------------*/
4496 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4498 TRACE("setting specular colour\n");
4500 e = &si->elements[WINED3D_FFP_SPECULAR];
4501 stream = &stateblock->state.streams[e->stream_idx];
4503 if (gl_info->supported[EXT_SECONDARY_COLOR])
4505 GLenum type = e->format->gl_vtx_type;
4506 GLint format = e->format->gl_vtx_format;
4508 if (curVBO != e->buffer_object)
4510 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4511 checkGLcall("glBindBufferARB");
4512 curVBO = e->buffer_object;
4515 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4517 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4518 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4519 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4520 * 4 component secondary colors use it
4522 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4523 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4524 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4525 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset));
4526 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4528 else
4530 switch(type)
4532 case GL_UNSIGNED_BYTE:
4533 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4534 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4535 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4536 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset));
4537 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4538 break;
4540 default:
4541 FIXME("Add 4 component specular color pointers for type %x\n", type);
4542 /* Make sure that the right color component is dropped */
4543 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4544 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset);
4545 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4546 e->data + stateblock->state.load_base_vertex_index * e->stride + stream->offset));
4547 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4550 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4551 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4553 else
4555 WARN("Specular colour is not supported in this GL implementation.\n");
4558 else
4560 if (gl_info->supported[EXT_SECONDARY_COLOR])
4562 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4563 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4565 else
4567 WARN("Specular colour is not supported in this GL implementation.\n");
4571 /* Texture coords -------------------------------------------*/
4572 loadTexCoords(gl_info, stateblock, si, &curVBO);
4575 static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4577 IWineD3DDeviceImpl *device = stateblock->device;
4578 BOOL load_numbered = use_vs(stateblock) && !device->useDrawStridedSlow;
4579 BOOL load_named = !use_vs(stateblock) && !device->useDrawStridedSlow;
4581 if (context->numberedArraysLoaded && !load_numbered)
4583 unloadNumberedArrays(context);
4584 context->numberedArraysLoaded = FALSE;
4585 context->numbered_array_mask = 0;
4587 else if (context->namedArraysLoaded)
4589 unloadVertexData(context->gl_info);
4590 context->namedArraysLoaded = FALSE;
4593 if (load_numbered)
4595 TRACE("Loading numbered arrays\n");
4596 loadNumberedArrays(stateblock, &device->strided_streams, context);
4597 context->numberedArraysLoaded = TRUE;
4599 else if (load_named)
4601 TRACE("Loading vertex data\n");
4602 loadVertexData(context, stateblock, &device->strided_streams);
4603 context->namedArraysLoaded = TRUE;
4607 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4609 const struct wined3d_gl_info *gl_info = context->gl_info;
4610 BOOL updateFog = FALSE;
4611 BOOL useVertexShaderFunction = use_vs(stateblock);
4612 BOOL usePixelShaderFunction = use_ps(stateblock);
4613 IWineD3DDeviceImpl *device = stateblock->device;
4614 BOOL transformed;
4615 BOOL wasrhw = context->last_was_rhw;
4616 unsigned int i;
4618 transformed = device->strided_streams.position_transformed;
4619 if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
4620 updateFog = TRUE;
4623 /* Reapply lighting if it is not scheduled for reapplication already */
4624 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
4625 state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
4628 if (transformed) {
4629 context->last_was_rhw = TRUE;
4630 } else {
4632 /* Untransformed, so relies on the view and projection matrices */
4633 context->last_was_rhw = FALSE;
4634 /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
4635 device->untransformed = TRUE;
4637 /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
4638 * Not needed as long as only hw shaders are supported
4641 /* This sets the shader output position correction constants.
4642 * TODO: Move to the viewport state
4644 if (useVertexShaderFunction)
4646 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->state.viewport.Height;
4647 device->posFixup[1] = context->render_offscreen ? -1.0f : 1.0f;
4648 device->posFixup[3] = device->posFixup[1] * yoffset;
4652 /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
4653 * off this function will be called again anyway to make sure they're properly set
4655 if(!useVertexShaderFunction) {
4656 /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
4657 * or transformed / untransformed was switched
4659 if(wasrhw != context->last_was_rhw &&
4660 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
4661 !isStateDirty(context, STATE_VIEWPORT)) {
4662 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4664 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4665 * mode.
4667 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4668 * this check will fail and the matrix not applied again. This is OK because a simple
4669 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4670 * needs of the vertex declaration.
4672 * World and view matrix go into the same gl matrix, so only apply them when neither is
4673 * dirty
4675 if(transformed != wasrhw &&
4676 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
4677 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
4678 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4681 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
4682 state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
4685 if(context->last_was_vshader) {
4686 updateFog = TRUE;
4687 if(!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
4688 state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
4690 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4692 clipplane(STATE_CLIPPLANE(i), stateblock, context);
4695 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
4696 state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
4698 } else {
4699 if(!context->last_was_vshader) {
4700 static BOOL warned = FALSE;
4701 if(!device->vs_clipping) {
4702 /* Disable all clip planes to get defined results on all drivers. See comment in the
4703 * state_clipping state handler
4705 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4707 glDisable(GL_CLIP_PLANE0 + i);
4708 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4711 if (!warned && stateblock->state.render_states[WINED3DRS_CLIPPLANEENABLE])
4713 FIXME("Clipping not supported with vertex shaders\n");
4714 warned = TRUE;
4717 if(wasrhw) {
4718 /* Apply the transform matrices when switching from rhw drawing to vertex shaders. Vertex
4719 * shaders themselves do not need it, but the matrices are not reapplied automatically when
4720 * switching back from vertex shaders to fixed function processing. So make sure we leave the
4721 * fixed function vertex processing states back in a sane state before switching to shaders
4723 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4724 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4726 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
4727 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4730 updateFog = TRUE;
4732 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4733 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4734 * device->vs_clipping is false.
4736 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4738 clipplane(STATE_CLIPPLANE(i), stateblock, context);
4743 /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
4744 * application
4746 if (!isStateDirty(context, STATE_PIXELSHADER)) {
4747 device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4749 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
4750 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
4754 context->last_was_vshader = useVertexShaderFunction;
4756 if (updateFog) stateblock_apply_state(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context);
4758 if(!useVertexShaderFunction) {
4759 int i;
4760 for(i = 0; i < MAX_TEXTURES; i++) {
4761 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i))) {
4762 transform_texture(STATE_TEXTURESTAGE(i, WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
4768 static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4770 IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0];
4771 UINT width, height;
4772 WINED3DVIEWPORT vp = stateblock->state.viewport;
4774 if(vp.Width > target->currentDesc.Width) vp.Width = target->currentDesc.Width;
4775 if(vp.Height > target->currentDesc.Height) vp.Height = target->currentDesc.Height;
4777 glDepthRange(vp.MinZ, vp.MaxZ);
4778 checkGLcall("glDepthRange");
4779 /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
4781 if (context->render_offscreen)
4783 glViewport(vp.X, vp.Y, vp.Width, vp.Height);
4784 } else {
4785 target->get_drawable_size(context, &width, &height);
4787 glViewport(vp.X,
4788 (height - (vp.Y + vp.Height)),
4789 vp.Width, vp.Height);
4792 checkGLcall("glViewport");
4795 static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4797 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->state.viewport.Height;
4799 stateblock->device->posFixup[2] = (63.0f / 64.0f) / stateblock->state.viewport.Width;
4800 stateblock->device->posFixup[3] = stateblock->device->posFixup[1] * yoffset;
4802 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4803 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4805 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
4806 state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
4808 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
4809 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
4812 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4814 UINT Index = state - STATE_ACTIVELIGHT(0);
4815 const struct wined3d_light_info *lightInfo = stateblock->state.lights[Index];
4817 if(!lightInfo) {
4818 glDisable(GL_LIGHT0 + Index);
4819 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4820 } else {
4821 float quad_att;
4822 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4824 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4825 glMatrixMode(GL_MODELVIEW);
4826 glPushMatrix();
4827 glLoadMatrixf(&stateblock->state.transforms[WINED3DTS_VIEW].u.m[0][0]);
4829 /* Diffuse: */
4830 colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
4831 colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
4832 colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
4833 colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
4834 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4835 checkGLcall("glLightfv");
4837 /* Specular */
4838 colRGBA[0] = lightInfo->OriginalParms.Specular.r;
4839 colRGBA[1] = lightInfo->OriginalParms.Specular.g;
4840 colRGBA[2] = lightInfo->OriginalParms.Specular.b;
4841 colRGBA[3] = lightInfo->OriginalParms.Specular.a;
4842 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4843 checkGLcall("glLightfv");
4845 /* Ambient */
4846 colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
4847 colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
4848 colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
4849 colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
4850 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4851 checkGLcall("glLightfv");
4853 if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
4854 quad_att = 1.4f/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
4855 } else {
4856 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4859 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4860 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4861 * Attenuation0 to NaN and crashes in the gl lib
4864 switch (lightInfo->OriginalParms.Type) {
4865 case WINED3DLIGHT_POINT:
4866 /* Position */
4867 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4868 checkGLcall("glLightfv");
4869 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4870 checkGLcall("glLightf");
4871 /* Attenuation - Are these right? guessing... */
4872 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
4873 checkGLcall("glLightf");
4874 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
4875 checkGLcall("glLightf");
4876 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4877 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4878 checkGLcall("glLightf");
4879 /* FIXME: Range */
4880 break;
4882 case WINED3DLIGHT_SPOT:
4883 /* Position */
4884 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4885 checkGLcall("glLightfv");
4886 /* Direction */
4887 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4888 checkGLcall("glLightfv");
4889 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4890 checkGLcall("glLightf");
4891 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4892 checkGLcall("glLightf");
4893 /* Attenuation - Are these right? guessing... */
4894 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
4895 checkGLcall("glLightf");
4896 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
4897 checkGLcall("glLightf");
4898 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4899 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4900 checkGLcall("glLightf");
4901 /* FIXME: Range */
4902 break;
4904 case WINED3DLIGHT_DIRECTIONAL:
4905 /* Direction */
4906 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4907 checkGLcall("glLightfv");
4908 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4909 checkGLcall("glLightf");
4910 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4911 checkGLcall("glLightf");
4912 break;
4914 default:
4915 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
4918 /* Restore the modelview matrix */
4919 glPopMatrix();
4921 glEnable(GL_LIGHT0 + Index);
4922 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4926 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4928 IWineD3DSurfaceImpl *target = stateblock->device->render_targets[0];
4929 RECT *pRect = &stateblock->state.scissor_rect;
4930 UINT height;
4931 UINT width;
4933 target->get_drawable_size(context, &width, &height);
4934 /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
4935 * Warning2: Even in windowed mode the coords are relative to the window, not the screen
4937 TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->device, pRect->left, pRect->bottom - height,
4938 pRect->right - pRect->left, pRect->bottom - pRect->top);
4940 if (context->render_offscreen)
4942 glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
4943 } else {
4944 glScissor(pRect->left, height - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
4946 checkGLcall("glScissor");
4949 static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4951 const struct wined3d_gl_info *gl_info = context->gl_info;
4953 if (stateblock->state.user_stream || !stateblock->state.index_buffer)
4955 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4957 else
4959 struct wined3d_buffer *ib = stateblock->state.index_buffer;
4960 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4964 static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4966 if (context->render_offscreen)
4968 glFrontFace(GL_CCW);
4969 checkGLcall("glFrontFace(GL_CCW)");
4970 } else {
4971 glFrontFace(GL_CW);
4972 checkGLcall("glFrontFace(GL_CW)");
4976 const struct StateEntryTemplate misc_state_template[] = {
4977 { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4978 { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4979 { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4980 { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4981 { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4982 { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4983 { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4984 { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4985 { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4986 { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4987 { STATE_STREAMSRC, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
4988 { STATE_VDECL, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE },
4989 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4990 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4991 /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and
4992 * vshader loadings are untied from each other
4994 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4995 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4996 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4997 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4998 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
4999 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5000 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5001 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5003 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5004 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5005 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5006 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5007 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5008 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5009 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5010 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5011 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5012 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5013 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5014 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5015 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5016 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5017 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5018 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5019 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5020 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5021 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5022 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5023 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5024 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5025 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5026 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5027 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), NULL }, WINED3D_GL_EXT_NONE },
5028 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5029 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5030 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5031 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5032 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5033 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5034 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5035 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5036 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5037 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5038 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5039 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5040 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5041 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5042 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5043 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), NULL }, WINED3D_GL_EXT_NONE },
5045 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
5046 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
5047 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
5048 { STATE_RENDER(WINED3DRS_ANTIALIAS), { STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
5050 { STATE_RENDER(WINED3DRS_ZENABLE), { STATE_RENDER(WINED3DRS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
5051 { STATE_RENDER(WINED3DRS_WRAPU), { STATE_RENDER(WINED3DRS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
5052 { STATE_RENDER(WINED3DRS_WRAPV), { STATE_RENDER(WINED3DRS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
5053 { STATE_RENDER(WINED3DRS_FILLMODE), { STATE_RENDER(WINED3DRS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
5054 { STATE_RENDER(WINED3DRS_SHADEMODE), { STATE_RENDER(WINED3DRS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
5055 { STATE_RENDER(WINED3DRS_LINEPATTERN), { STATE_RENDER(WINED3DRS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
5056 { STATE_RENDER(WINED3DRS_MONOENABLE), { STATE_RENDER(WINED3DRS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
5057 { STATE_RENDER(WINED3DRS_ROP2), { STATE_RENDER(WINED3DRS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
5058 { STATE_RENDER(WINED3DRS_PLANEMASK), { STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
5059 { STATE_RENDER(WINED3DRS_ZWRITEENABLE), { STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
5060 { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
5061 { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5062 { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5063 { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5064 { STATE_RENDER(WINED3DRS_LASTPIXEL), { STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
5065 { STATE_RENDER(WINED3DRS_CULLMODE), { STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
5066 { STATE_RENDER(WINED3DRS_ZFUNC), { STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
5067 { STATE_RENDER(WINED3DRS_DITHERENABLE), { STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
5068 { STATE_RENDER(WINED3DRS_SUBPIXEL), { STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
5069 { STATE_RENDER(WINED3DRS_SUBPIXELX), { STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
5070 { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
5071 { STATE_RENDER(WINED3DRS_ZBIAS), { STATE_RENDER(WINED3DRS_ZBIAS), state_zbias }, WINED3D_GL_EXT_NONE },
5072 { STATE_RENDER(WINED3DRS_STIPPLEENABLE), { STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
5073 { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
5074 { STATE_RENDER(WINED3DRS_ANISOTROPY), { STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
5075 { STATE_RENDER(WINED3DRS_FLUSHBATCH), { STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
5076 { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, WINED3D_GL_EXT_NONE },
5077 { STATE_RENDER(WINED3DRS_STENCILENABLE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
5078 { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5079 { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5080 { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5081 { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5082 { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5083 { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5084 { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
5085 { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
5086 { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5087 { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5088 { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5089 { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5090 { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5091 { STATE_RENDER(WINED3DRS_WRAP0), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5092 { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5093 { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5094 { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5095 { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5096 { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5097 { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5098 { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5099 { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5100 { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5101 { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5102 { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5103 { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5104 { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5105 { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5106 { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5107 { STATE_RENDER(WINED3DRS_EXTENTS), { STATE_RENDER(WINED3DRS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5108 { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5109 { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3DRS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5110 { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5111 { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5112 { STATE_RENDER(WINED3DRS_POSITIONDEGREE), { STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5113 { STATE_RENDER(WINED3DRS_NORMALDEGREE), { STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5114 { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5115 { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5116 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5117 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5118 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5119 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), NULL }, WINED3D_GL_EXT_NONE },
5120 { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5121 { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
5122 { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5123 { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5124 { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5125 { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5126 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5127 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5128 { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5129 { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5130 { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5131 { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5132 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5133 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5134 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5135 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5136 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5137 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5138 { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5139 { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5140 { STATE_RENDER(WINED3DRS_DEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5141 { STATE_RENDER(WINED3DRS_ZVISIBLE), { STATE_RENDER(WINED3DRS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5142 /* Samplers */
5143 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5144 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5145 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5146 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5147 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5148 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5149 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5150 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5151 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5152 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5153 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5154 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5155 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5156 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5157 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5158 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5159 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5160 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5161 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5162 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5163 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5166 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5167 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5168 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5169 { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5170 { STATE_RENDER(WINED3DRS_SPECULARENABLE), { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5171 /* Clip planes */
5172 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5173 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5174 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5175 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5176 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5177 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5178 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5179 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5180 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5181 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5182 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5183 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5184 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5185 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5186 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5187 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5188 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5189 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5190 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5191 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5192 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5193 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5194 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5195 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5196 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5197 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5198 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5199 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5200 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5201 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5202 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5203 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5204 /* Lights */
5205 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5206 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5207 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5208 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5209 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5210 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5211 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5212 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5213 /* Viewport */
5214 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5215 /* Transform states follow */
5216 { STATE_TRANSFORM(WINED3DTS_VIEW), { STATE_TRANSFORM(WINED3DTS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3DTS_PROJECTION), { STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), NULL }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 3)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 4)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 5)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 6)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 7)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 8)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 9)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5396 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5397 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5400 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5401 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5402 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5403 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5405 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5406 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5407 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5411 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5412 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5413 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5414 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5415 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5416 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5417 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5418 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5419 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5420 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5421 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5422 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5423 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5424 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5425 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5426 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5427 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5428 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5429 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5430 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5431 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5432 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5433 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5434 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5435 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5436 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5437 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5438 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5439 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5440 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5441 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5442 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5443 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5444 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5445 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5446 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5447 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5448 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5449 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5450 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5451 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5452 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5453 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5454 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5455 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5456 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5457 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5458 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5459 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5460 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5461 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5462 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5463 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5464 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5465 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5466 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5467 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5468 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5469 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5470 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5471 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5472 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5473 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5474 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5475 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5476 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5477 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5478 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5479 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5480 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5481 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5482 { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5483 { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5484 { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5485 { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5486 { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5487 { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5488 { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5489 { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5490 { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5491 { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5492 { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5493 { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5494 { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5495 { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5496 { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5497 { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5498 /* Fog */
5499 { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5500 { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5501 { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5502 { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog }, NV_FOG_DISTANCE },
5503 { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog_w }, WINED3D_GL_EXT_NONE },
5504 { STATE_RENDER(WINED3DRS_CLIPPING), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5505 { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5506 { STATE_RENDER(WINED3DRS_LIGHTING), { STATE_RENDER(WINED3DRS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5507 { STATE_RENDER(WINED3DRS_AMBIENT), { STATE_RENDER(WINED3DRS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5508 { STATE_RENDER(WINED3DRS_COLORVERTEX), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5509 { STATE_RENDER(WINED3DRS_LOCALVIEWER), { STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5510 { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5511 { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5512 { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5513 { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5514 { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5515 { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5516 { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5517 { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5518 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5519 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5520 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5521 { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5522 { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5523 { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5524 { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5525 { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5526 { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5527 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5528 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5529 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5530 { STATE_RENDER(WINED3DRS_TWEENFACTOR), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5531 { STATE_RENDER(WINED3DRS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3DRS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5533 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5534 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5535 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5537 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5538 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5539 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5540 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5541 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5542 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5543 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5544 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5545 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5546 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5547 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5548 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5549 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5550 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5551 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5552 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5553 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5554 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5555 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5556 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5557 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5558 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5559 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5560 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5561 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5564 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5565 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5566 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5567 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5568 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5569 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5570 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5571 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5572 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5573 { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5574 { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5575 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5576 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5577 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5578 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5579 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5580 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5581 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5582 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5583 { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5584 { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5585 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5586 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5587 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5588 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5589 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5590 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5591 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5592 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5593 { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5594 { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5595 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5596 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5597 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5598 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5599 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5600 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5601 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5602 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5603 { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5604 { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5605 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5606 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5607 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5608 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5609 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5610 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5611 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5612 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5613 { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5614 { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5615 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5616 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5617 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5618 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5619 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5620 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5621 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5622 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5623 { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5624 { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5625 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5626 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5627 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5628 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5629 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5630 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5631 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5632 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5633 { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5634 { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5635 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5636 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5637 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5638 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5639 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5640 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5641 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5642 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), NULL }, WINED3D_GL_EXT_NONE },
5643 { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), NULL }, WINED3D_GL_EXT_NONE },
5644 { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5645 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5646 { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5647 { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5648 { STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5649 { STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5650 { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5651 { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5652 { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5653 { STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5654 { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5655 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5656 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5657 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5658 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5659 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5660 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5661 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5662 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5663 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5666 /* Context activation is done by the caller. */
5667 static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
5669 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
5671 pCaps->PrimitiveMiscCaps = 0;
5672 pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD |
5673 WINED3DTEXOPCAPS_ADDSIGNED |
5674 WINED3DTEXOPCAPS_ADDSIGNED2X |
5675 WINED3DTEXOPCAPS_MODULATE |
5676 WINED3DTEXOPCAPS_MODULATE2X |
5677 WINED3DTEXOPCAPS_MODULATE4X |
5678 WINED3DTEXOPCAPS_SELECTARG1 |
5679 WINED3DTEXOPCAPS_SELECTARG2 |
5680 WINED3DTEXOPCAPS_DISABLE;
5682 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5683 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5684 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5686 pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
5687 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA |
5688 WINED3DTEXOPCAPS_BLENDFACTORALPHA |
5689 WINED3DTEXOPCAPS_BLENDCURRENTALPHA |
5690 WINED3DTEXOPCAPS_LERP |
5691 WINED3DTEXOPCAPS_SUBTRACT;
5693 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5694 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5696 pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH |
5697 WINED3DTEXOPCAPS_MULTIPLYADD |
5698 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
5699 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
5700 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5702 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5703 pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5705 pCaps->MaxTextureBlendStages = gl_info->limits.textures;
5706 pCaps->MaxSimultaneousTextures = gl_info->limits.textures;
5709 static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
5710 static void ffp_fragment_free(IWineD3DDevice *iface) {}
5711 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5713 if (TRACE_ON(d3d))
5715 TRACE("Checking support for fixup:\n");
5716 dump_color_fixup_desc(fixup);
5719 /* We only support identity conversions. */
5720 if (is_identity_fixup(fixup))
5722 TRACE("[OK]\n");
5723 return TRUE;
5726 TRACE("[FAILED]\n");
5727 return FALSE;
5730 const struct fragment_pipeline ffp_fragment_pipeline = {
5731 ffp_enable,
5732 ffp_fragment_get_caps,
5733 ffp_fragment_alloc,
5734 ffp_fragment_free,
5735 ffp_color_fixup_supported,
5736 ffp_fragmentstate_template,
5737 FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5740 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5742 unsigned int i;
5743 for(i = 0; funcs[i]; i++);
5744 return i;
5747 static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
5749 stateblock->device->multistate_funcs[state][0](state, stateblock, context);
5750 stateblock->device->multistate_funcs[state][1](state, stateblock, context);
5753 static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
5755 stateblock->device->multistate_funcs[state][0](state, stateblock, context);
5756 stateblock->device->multistate_funcs[state][1](state, stateblock, context);
5757 stateblock->device->multistate_funcs[state][2](state, stateblock, context);
5760 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5762 unsigned int start, last, i;
5764 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5765 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5766 for (i = start; i <= last; ++i)
5768 state_table[i].representative = 0;
5769 state_table[i].apply = state_undefined;
5772 start = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + gl_info->limits.texture_stages);
5773 last = STATE_TRANSFORM(WINED3DTS_TEXTURE0 + MAX_TEXTURES - 1);
5774 for (i = start; i <= last; ++i)
5776 state_table[i].representative = 0;
5777 state_table[i].apply = state_undefined;
5780 start = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(gl_info->limits.blends));
5781 last = STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255));
5782 for (i = start; i <= last; ++i)
5784 state_table[i].representative = 0;
5785 state_table[i].apply = state_undefined;
5789 static void validate_state_table(struct StateEntry *state_table)
5791 static const struct
5793 DWORD first;
5794 DWORD last;
5796 rs_holes[] =
5798 { 1, 1},
5799 { 3, 3},
5800 { 17, 18},
5801 { 21, 21},
5802 { 42, 45},
5803 { 61, 127},
5804 {149, 150},
5805 {169, 169},
5806 {177, 177},
5807 {196, 197},
5808 { 0, 0},
5810 static const DWORD simple_states[] =
5812 STATE_MATERIAL,
5813 STATE_VDECL,
5814 STATE_STREAMSRC,
5815 STATE_INDEXBUFFER,
5816 STATE_VERTEXSHADERCONSTANT,
5817 STATE_PIXELSHADERCONSTANT,
5818 STATE_VSHADER,
5819 STATE_PIXELSHADER,
5820 STATE_VIEWPORT,
5821 STATE_SCISSORRECT,
5822 STATE_FRONTFACE,
5824 unsigned int i, current;
5826 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5828 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5830 if (!state_table[i].representative)
5831 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5833 else if (state_table[i].representative)
5834 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5836 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5839 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5841 if (!state_table[simple_states[i]].representative)
5842 ERR("State %s (%#x) should have a representative.\n",
5843 debug_d3dstate(simple_states[i]), simple_states[i]);
5846 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5848 DWORD rep = state_table[i].representative;
5849 if (rep)
5851 if (state_table[rep].representative != rep)
5853 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5854 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5855 state_table[i].representative = 0;
5858 if (rep != i)
5860 if (state_table[i].apply)
5861 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5863 else if (!state_table[i].apply)
5865 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5871 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5872 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5873 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5875 unsigned int i, type, handlers;
5876 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5877 const struct StateEntryTemplate *cur;
5878 BOOL set[STATE_HIGHEST + 1];
5880 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5882 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5883 StateTable[i].representative = 0;
5884 StateTable[i].apply = state_undefined;
5887 for(type = 0; type < 3; type++) {
5888 /* This switch decides the order in which the states are applied */
5889 switch(type) {
5890 case 0: cur = misc; break;
5891 case 1: cur = fragment->states; break;
5892 case 2: cur = vertex; break;
5893 default: cur = NULL; /* Stupid compiler */
5895 if(!cur) continue;
5897 /* GL extension filtering should not prevent multiple handlers being applied from different
5898 * pipeline parts
5900 memset(set, 0, sizeof(set));
5902 for(i = 0; cur[i].state; i++) {
5903 APPLYSTATEFUNC *funcs_array;
5905 /* Only use the first matching state with the available extension from one template.
5906 * e.g.
5907 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5908 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5910 * if GL_XYZ_fancy is supported, ignore the 2nd line
5912 if(set[cur[i].state]) continue;
5913 /* Skip state lines depending on unsupported extensions */
5914 if (!gl_info->supported[cur[i].extension]) continue;
5915 set[cur[i].state] = TRUE;
5916 /* In some cases having an extension means that nothing has to be
5917 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5918 * supported, the texture coordinate fixup can be ignored. If the
5919 * apply function is used, mark the state set(done above) to prevent
5920 * applying later lines, but do not record anything in the state
5921 * table
5923 if (!cur[i].content.representative) continue;
5925 handlers = num_handlers(multistate_funcs[cur[i].state]);
5926 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5927 switch(handlers) {
5928 case 0:
5929 StateTable[cur[i].state].apply = cur[i].content.apply;
5930 break;
5931 case 1:
5932 StateTable[cur[i].state].apply = multistate_apply_2;
5933 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5935 sizeof(**dev_multistate_funcs) * 2);
5936 if (!dev_multistate_funcs[cur[i].state]) {
5937 goto out_of_mem;
5940 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5941 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5942 break;
5943 case 2:
5944 StateTable[cur[i].state].apply = multistate_apply_3;
5945 funcs_array = HeapReAlloc(GetProcessHeap(),
5947 dev_multistate_funcs[cur[i].state],
5948 sizeof(**dev_multistate_funcs) * 3);
5949 if (!funcs_array) {
5950 goto out_of_mem;
5953 dev_multistate_funcs[cur[i].state] = funcs_array;
5954 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5955 break;
5956 default:
5957 ERR("Unexpected amount of state handlers for state %u: %u\n",
5958 cur[i].state, handlers + 1);
5961 if(StateTable[cur[i].state].representative &&
5962 StateTable[cur[i].state].representative != cur[i].content.representative) {
5963 FIXME("State %u has different representatives in different pipeline parts\n",
5964 cur[i].state);
5966 StateTable[cur[i].state].representative = cur[i].content.representative;
5970 prune_invalid_states(StateTable, gl_info);
5971 validate_state_table(StateTable);
5973 return WINED3D_OK;
5975 out_of_mem:
5976 for (i = 0; i <= STATE_HIGHEST; ++i) {
5977 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5980 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5982 return E_OUTOFMEMORY;