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-2007 Stefan Dösinger for CodeWeavers
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wined3d_private.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
35 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
37 #define GLINFO_LOCATION ((IWineD3DImpl *)(stateblock->wineD3DDevice->wineD3D))->gl_info
39 static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
40 /* Used for states which are not mapped to a gl state as-is, but used somehow different,
41 * e.g as a parameter for drawing, or which are unimplemented in windows d3d
43 if(STATE_IS_RENDER(state)) {
44 WINED3DRENDERSTATETYPE RenderState = state - STATE_RENDER(0);
45 TRACE("(%s,%d) no direct mapping to gl\n", debug_d3drenderstate(RenderState), stateblock->renderState[RenderState]);
47 /* Shouldn't have an unknown type here */
48 FIXME("%d no direct mapping to gl of state with unknown type\n", state);
52 static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
53 /* Print a WARN, this allows the stateblock code to loop over all states to generate a display
54 * list without causing confusing terminal output. Deliberately no special debug name here
55 * because its undefined.
57 WARN("undefined state %d\n", state);
60 static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
61 WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
64 case WINED3DFILL_POINT:
65 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
66 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
68 case WINED3DFILL_WIREFRAME:
69 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
70 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
72 case WINED3DFILL_SOLID:
73 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
74 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
77 FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
81 static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
84 /* Lighting is not enabled if transformed vertices are drawn
85 * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
86 * This state reads the decoded vertex decl, so if it is dirty don't do anything. The
87 * vertex declaration appplying function calls this function for updating
90 if(isStateDirty(context, STATE_VDECL)) {
94 transformed = ((stateblock->wineD3DDevice->strided_streams.u.s.position.lpData != NULL ||
95 stateblock->wineD3DDevice->strided_streams.u.s.position.VBO != 0) &&
96 stateblock->wineD3DDevice->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
98 if (stateblock->renderState[WINED3DRS_LIGHTING] && !transformed) {
99 glEnable(GL_LIGHTING);
100 checkGLcall("glEnable GL_LIGHTING");
102 glDisable(GL_LIGHTING);
103 checkGLcall("glDisable GL_LIGHTING");
107 static void state_zenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
108 switch ((WINED3DZBUFFERTYPE) stateblock->renderState[WINED3DRS_ZENABLE]) {
109 case WINED3DZB_FALSE:
110 glDisable(GL_DEPTH_TEST);
111 checkGLcall("glDisable GL_DEPTH_TEST");
114 glEnable(GL_DEPTH_TEST);
115 checkGLcall("glEnable GL_DEPTH_TEST");
118 glEnable(GL_DEPTH_TEST);
119 checkGLcall("glEnable GL_DEPTH_TEST");
120 FIXME("W buffer is not well handled\n");
123 FIXME("Unrecognized D3DZBUFFERTYPE value %d\n", stateblock->renderState[WINED3DRS_ZENABLE]);
127 static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
128 /* TODO: Put this into the offscreen / onscreen rendering block due to device->render_offscreen */
130 /* If we are culling "back faces with clockwise vertices" then
131 set front faces to be counter clockwise and enable culling
133 switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
134 case WINED3DCULL_NONE:
135 glDisable(GL_CULL_FACE);
136 checkGLcall("glDisable GL_CULL_FACE");
139 glEnable(GL_CULL_FACE);
140 checkGLcall("glEnable GL_CULL_FACE");
141 if (stateblock->wineD3DDevice->render_offscreen) {
143 checkGLcall("glFrontFace GL_CW");
146 checkGLcall("glFrontFace GL_CCW");
150 case WINED3DCULL_CCW:
151 glEnable(GL_CULL_FACE);
152 checkGLcall("glEnable GL_CULL_FACE");
153 if (stateblock->wineD3DDevice->render_offscreen) {
155 checkGLcall("glFrontFace GL_CCW");
158 checkGLcall("glFrontFace GL_CW");
163 FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]);
167 static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
168 switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) {
169 case WINED3DSHADE_FLAT:
170 glShadeModel(GL_FLAT);
171 checkGLcall("glShadeModel(GL_FLAT)");
173 case WINED3DSHADE_GOURAUD:
174 glShadeModel(GL_SMOOTH);
175 checkGLcall("glShadeModel(GL_SMOOTH)");
177 case WINED3DSHADE_PHONG:
178 FIXME("WINED3DSHADE_PHONG isn't supported\n");
181 FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %d\n", stateblock->renderState[WINED3DRS_SHADEMODE]);
185 static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
186 if (stateblock->renderState[WINED3DRS_DITHERENABLE]) {
188 checkGLcall("glEnable GL_DITHER");
190 glDisable(GL_DITHER);
191 checkGLcall("glDisable GL_DITHER");
195 static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
196 /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes,
197 * this has to be merged with ZENABLE and ZFUNC
199 if (stateblock->renderState[WINED3DRS_ZWRITEENABLE]) {
201 checkGLcall("glDepthMask(1)");
204 checkGLcall("glDepthMask(0)");
208 static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
209 int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
213 checkGLcall("glDepthFunc");
217 static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
219 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
221 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
222 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
223 checkGLcall("glLightModel for MODEL_AMBIENT");
226 static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
227 int srcBlend = GL_ZERO;
228 int dstBlend = GL_ZERO;
230 /* GL_LINE_SMOOTH needs GL_BLEND to work, according to the red book, and special blending params */
231 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE] ||
232 stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
233 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
235 checkGLcall("glEnable GL_BLEND");
238 checkGLcall("glDisable GL_BLEND");
239 /* Nothing more to do - get out */
243 switch (stateblock->renderState[WINED3DRS_SRCBLEND]) {
244 case WINED3DBLEND_ZERO : srcBlend = GL_ZERO; break;
245 case WINED3DBLEND_ONE : srcBlend = GL_ONE; break;
246 case WINED3DBLEND_SRCCOLOR : srcBlend = GL_SRC_COLOR; break;
247 case WINED3DBLEND_INVSRCCOLOR : srcBlend = GL_ONE_MINUS_SRC_COLOR; break;
248 case WINED3DBLEND_SRCALPHA : srcBlend = GL_SRC_ALPHA; break;
249 case WINED3DBLEND_INVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA; break;
250 case WINED3DBLEND_DESTALPHA : srcBlend = GL_DST_ALPHA; break;
251 case WINED3DBLEND_INVDESTALPHA : srcBlend = GL_ONE_MINUS_DST_ALPHA; break;
252 case WINED3DBLEND_DESTCOLOR : srcBlend = GL_DST_COLOR; break;
253 case WINED3DBLEND_INVDESTCOLOR : srcBlend = GL_ONE_MINUS_DST_COLOR; break;
254 case WINED3DBLEND_SRCALPHASAT : srcBlend = GL_SRC_ALPHA_SATURATE; break;
256 case WINED3DBLEND_BOTHSRCALPHA : srcBlend = GL_SRC_ALPHA;
257 dstBlend = GL_SRC_ALPHA;
260 case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
261 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
264 case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR; break;
265 case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
267 FIXME("Unrecognized src blend value %d\n", stateblock->renderState[WINED3DRS_SRCBLEND]);
270 switch (stateblock->renderState[WINED3DRS_DESTBLEND]) {
271 case WINED3DBLEND_ZERO : dstBlend = GL_ZERO; break;
272 case WINED3DBLEND_ONE : dstBlend = GL_ONE; break;
273 case WINED3DBLEND_SRCCOLOR : dstBlend = GL_SRC_COLOR; break;
274 case WINED3DBLEND_INVSRCCOLOR : dstBlend = GL_ONE_MINUS_SRC_COLOR; break;
275 case WINED3DBLEND_SRCALPHA : dstBlend = GL_SRC_ALPHA; break;
276 case WINED3DBLEND_INVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA; break;
277 case WINED3DBLEND_DESTALPHA : dstBlend = GL_DST_ALPHA; break;
278 case WINED3DBLEND_INVDESTALPHA : dstBlend = GL_ONE_MINUS_DST_ALPHA; break;
279 case WINED3DBLEND_DESTCOLOR : dstBlend = GL_DST_COLOR; break;
280 case WINED3DBLEND_INVDESTCOLOR : dstBlend = GL_ONE_MINUS_DST_COLOR; break;
281 case WINED3DBLEND_SRCALPHASAT : dstBlend = GL_SRC_ALPHA_SATURATE; break;
283 case WINED3DBLEND_BOTHSRCALPHA : dstBlend = GL_SRC_ALPHA;
284 srcBlend = GL_SRC_ALPHA;
287 case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
288 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
291 case WINED3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR; break;
292 case WINED3DBLEND_INVBLENDFACTOR : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
294 FIXME("Unrecognized dst blend value %d\n", stateblock->renderState[WINED3DRS_DESTBLEND]);
297 if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
298 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
299 glEnable(GL_LINE_SMOOTH);
300 checkGLcall("glEnable(GL_LINE_SMOOTH)");
301 if(srcBlend != GL_SRC_ALPHA) {
302 FIXME("WINED3DRS_EDGEANTIALIAS enabled, but incompatible src blending param - what to do?\n");
303 srcBlend = GL_SRC_ALPHA;
305 if(dstBlend != GL_ONE_MINUS_SRC_ALPHA) {
306 FIXME("WINED3DRS_EDGEANTIALIAS enabled, but incompatible dst blending param - what to do?\n");
307 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
310 glDisable(GL_LINE_SMOOTH);
311 checkGLcall("glDisable(GL_LINE_SMOOTH)");
314 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
315 glBlendFunc(srcBlend, dstBlend);
316 checkGLcall("glBlendFunc");
319 static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
322 TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
323 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col);
324 glBlendColor (col[0],col[1],col[2],col[3]);
325 checkGLcall("glBlendColor");
328 static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
331 BOOL enable_ckey = FALSE;
333 IWineD3DSurfaceImpl *surf;
335 /* Find out if the texture on the first stage has a ckey set
336 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
337 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
338 * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
339 * in case it finds some texture+colorkeyenable combination which needs extra care.
341 if(stateblock->textures[0] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) {
342 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
344 if(surf->CKeyFlags & DDSD_CKSRCBLT) {
345 const PixelFormatDesc *fmt = getFormatDescEntry(surf->resource.format);
346 /* The surface conversion does not do color keying conversion for surfaces that have an alpha
347 * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
348 * surface has alpha bits
350 if(fmt->alphaMask == 0x00000000) {
356 if(enable_ckey || context->last_was_ckey) {
357 StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
359 context->last_was_ckey = enable_ckey;
361 if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
362 (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) {
363 glEnable(GL_ALPHA_TEST);
364 checkGLcall("glEnable GL_ALPHA_TEST");
366 glDisable(GL_ALPHA_TEST);
367 checkGLcall("glDisable GL_ALPHA_TEST");
368 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
374 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
375 glParm = GL_NOTEQUAL;
378 ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
379 glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
382 glAlphaFunc(glParm, ref);
383 checkGLcall("glAlphaFunc");
387 static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
388 DWORD enable = 0xFFFFFFFF;
389 DWORD disable = 0x00000000;
391 /* TODO: Keep track of previously enabled clipplanes to avoid unneccessary resetting
392 * of already set values
395 /* If enabling / disabling all
396 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
398 if (stateblock->renderState[WINED3DRS_CLIPPING]) {
399 enable = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
400 disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
402 disable = 0xffffffff;
406 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
407 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
408 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
409 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
410 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
411 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
413 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
414 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
415 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
416 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
417 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
418 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
420 /** update clipping status */
422 stateblock->clip_status.ClipUnion = 0;
423 stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
425 stateblock->clip_status.ClipUnion = 0;
426 stateblock->clip_status.ClipIntersection = 0;
430 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
431 int glParm = GL_FUNC_ADD;
433 if(!GL_SUPPORT(EXT_BLEND_MINMAX)) {
434 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
438 switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOP]) {
439 case WINED3DBLENDOP_ADD : glParm = GL_FUNC_ADD; break;
440 case WINED3DBLENDOP_SUBTRACT : glParm = GL_FUNC_SUBTRACT; break;
441 case WINED3DBLENDOP_REVSUBTRACT : glParm = GL_FUNC_REVERSE_SUBTRACT; break;
442 case WINED3DBLENDOP_MIN : glParm = GL_MIN; break;
443 case WINED3DBLENDOP_MAX : glParm = GL_MAX; break;
445 FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOP]);
448 TRACE("glBlendEquation(%x)\n", glParm);
449 GL_EXTCALL(glBlendEquation(glParm));
450 checkGLcall("glBlendEquation");
454 state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
455 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
456 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
457 * specular color. This is wrong:
458 * Separate specular color means the specular colour is maintained separately, whereas
459 * single color means it is merged in. However in both cases they are being used to
461 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
462 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
466 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
467 * Instead, we need to setup the FinalCombiner properly.
469 * The default setup for the FinalCombiner is:
471 * <variable> <input> <mapping> <usage>
472 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
473 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
474 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
475 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
476 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
477 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
478 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
480 * That's pretty much fine as it is, except for variable B, which needs to take
481 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
482 * whether WINED3DRS_SPECULARENABLE is enabled or not.
485 TRACE("Setting specular enable state\n");
486 /* TODO: Add to the material setting functions */
487 if (stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
488 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &stateblock->material.Specular);
489 checkGLcall("glMaterialfv");
490 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
491 glEnable(GL_COLOR_SUM_EXT);
493 TRACE("Specular colors cannot be enabled in this version of opengl\n");
495 checkGLcall("glEnable(GL_COLOR_SUM)");
497 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
498 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
499 checkGLcall("glFinalCombinerInputNV()");
502 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
504 /* for the case of enabled lighting: */
505 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
506 checkGLcall("glMaterialfv");
508 /* for the case of disabled lighting: */
509 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
510 glDisable(GL_COLOR_SUM_EXT);
512 TRACE("Specular colors cannot be disabled in this version of opengl\n");
514 checkGLcall("glDisable(GL_COLOR_SUM)");
516 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
517 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
518 checkGLcall("glFinalCombinerInputNV()");
523 static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
526 /* Note the texture color applies to all textures whereas
527 * GL_TEXTURE_ENV_COLOR applies to active only
530 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
532 if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
533 /* And now the default texture color as well */
534 for (i = 0; i < GL_LIMITS(texture_stages); i++) {
535 /* Note the WINED3DRS value applies to all textures, but GL has one
536 * per texture, so apply it now ready to be used!
538 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
539 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
540 checkGLcall("glActiveTextureARB");
542 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
545 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
546 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
549 GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
554 renderstate_stencil_twosided(IWineD3DStateBlockImpl *stateblock, GLint face, GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass ) {
555 #if 0 /* Don't use OpenGL 2.0 calls for now */
556 if(GL_EXTCALL(glStencilFuncSeparate) && GL_EXTCALL(glStencilOpSeparate)) {
557 GL_EXTCALL(glStencilFuncSeparate(face, func, ref, mask));
558 checkGLcall("glStencilFuncSeparate(...)");
559 GL_EXTCALL(glStencilOpSeparate(face, stencilFail, depthFail, stencilPass));
560 checkGLcall("glStencilOpSeparate(...)");
564 if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
565 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
566 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
567 GL_EXTCALL(glActiveStencilFaceEXT(face));
568 checkGLcall("glActiveStencilFaceEXT(...)");
569 glStencilFunc(func, ref, mask);
570 checkGLcall("glStencilFunc(...)");
571 glStencilOp(stencilFail, depthFail, stencilPass);
572 checkGLcall("glStencilOp(...)");
573 } else if(GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
574 GL_EXTCALL(glStencilFuncSeparateATI(face, func, ref, mask));
575 checkGLcall("glStencilFuncSeparateATI(...)");
576 GL_EXTCALL(glStencilOpSeparateATI(face, stencilFail, depthFail, stencilPass));
577 checkGLcall("glStencilOpSeparateATI(...)");
579 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
584 state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
585 DWORD onesided_enable = FALSE;
586 DWORD twosided_enable = FALSE;
587 GLint func = GL_ALWAYS;
588 GLint func_ccw = GL_ALWAYS;
591 GLint stencilFail = GL_KEEP;
592 GLint depthFail = GL_KEEP;
593 GLint stencilPass = GL_KEEP;
594 GLint stencilFail_ccw = GL_KEEP;
595 GLint depthFail_ccw = GL_KEEP;
596 GLint stencilPass_ccw = GL_KEEP;
598 if( stateblock->set.renderState[WINED3DRS_STENCILENABLE] )
599 onesided_enable = stateblock->renderState[WINED3DRS_STENCILENABLE];
600 if( stateblock->set.renderState[WINED3DRS_TWOSIDEDSTENCILMODE] )
601 twosided_enable = stateblock->renderState[WINED3DRS_TWOSIDEDSTENCILMODE];
602 if( stateblock->set.renderState[WINED3DRS_STENCILFUNC] )
603 if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
605 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFUNC] )
606 if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
608 if( stateblock->set.renderState[WINED3DRS_STENCILREF] )
609 ref = stateblock->renderState[WINED3DRS_STENCILREF];
610 if( stateblock->set.renderState[WINED3DRS_STENCILMASK] )
611 mask = stateblock->renderState[WINED3DRS_STENCILMASK];
612 if( stateblock->set.renderState[WINED3DRS_STENCILFAIL] )
613 stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
614 if( stateblock->set.renderState[WINED3DRS_STENCILZFAIL] )
615 depthFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILZFAIL]);
616 if( stateblock->set.renderState[WINED3DRS_STENCILPASS] )
617 stencilPass = StencilOp(stateblock->renderState[WINED3DRS_STENCILPASS]);
618 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFAIL] )
619 stencilFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILFAIL]);
620 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILZFAIL] )
621 depthFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILZFAIL]);
622 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILPASS] )
623 stencilPass_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILPASS]);
625 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
626 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
627 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
628 onesided_enable, twosided_enable, ref, mask,
629 func, stencilFail, depthFail, stencilPass,
630 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
632 if (twosided_enable) {
633 renderstate_stencil_twosided(stateblock, GL_FRONT, func, ref, mask, stencilFail, depthFail, stencilPass);
634 renderstate_stencil_twosided(stateblock, GL_BACK, func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
636 if (onesided_enable) {
637 glEnable(GL_STENCIL_TEST);
638 checkGLcall("glEnable GL_STENCIL_TEST");
639 glStencilFunc(func, ref, mask);
640 checkGLcall("glStencilFunc(...)");
641 glStencilOp(stencilFail, depthFail, stencilPass);
642 checkGLcall("glStencilOp(...)");
644 glDisable(GL_STENCIL_TEST);
645 checkGLcall("glDisable GL_STENCIL_TEST");
650 static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
651 glStencilMask(stateblock->renderState[WINED3DRS_STENCILWRITEMASK]);
652 checkGLcall("glStencilMask");
655 static void state_fog(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
656 /* TODO: Put this into the vertex type block once that is in the state table */
657 BOOL fogenable = stateblock->renderState[WINED3DRS_FOGENABLE];
658 float fogstart, fogend;
666 /* No fog? Disable it, and we're done :-) */
668 checkGLcall("glDisable GL_FOG");
671 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
672 fogstart = tmpvalue.f;
673 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
676 /* Activate when vertex shaders are in the state table */
677 if(stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function &&
678 ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog) {
679 glFogi(GL_FOG_MODE, GL_LINEAR);
680 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
681 if (stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
685 context->last_was_foggy_shader = TRUE;
687 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
688 * the system will apply only pixel(=table) fog effects."
690 else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
691 glHint(GL_FOG_HINT, GL_FASTEST);
692 checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
693 context->last_was_foggy_shader = FALSE;
695 switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
696 /* Processed vertices have their fog factor stored in the specular value. Fall too the none case.
697 * If we are drawing untransformed vertices atm, d3ddevice_set_ortho will update the fog
699 case WINED3DFOG_EXP: {
700 if(!context->last_was_rhw) {
701 glFogi(GL_FOG_MODE, GL_EXP);
702 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
703 if(GL_SUPPORT(EXT_FOG_COORD)) {
704 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
705 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
710 case WINED3DFOG_EXP2: {
711 if(!context->last_was_rhw) {
712 glFogi(GL_FOG_MODE, GL_EXP2);
713 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
714 if(GL_SUPPORT(EXT_FOG_COORD)) {
715 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
716 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
721 case WINED3DFOG_LINEAR: {
722 if(!context->last_was_rhw) {
723 glFogi(GL_FOG_MODE, GL_LINEAR);
724 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
725 if(GL_SUPPORT(EXT_FOG_COORD)) {
726 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
727 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
732 case WINED3DFOG_NONE: {
733 /* Both are none? According to msdn the alpha channel of the specular
734 * color contains a fog factor. Set it in drawStridedSlow.
735 * Same happens with Vertexfog on transformed vertices
737 if(GL_SUPPORT(EXT_FOG_COORD)) {
738 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
739 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
740 glFogi(GL_FOG_MODE, GL_LINEAR);
741 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
745 /* Disable GL fog, handle this in software in drawStridedSlow */
750 default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
753 glHint(GL_FOG_HINT, GL_NICEST);
754 checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
755 context->last_was_foggy_shader = FALSE;
757 switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
759 glFogi(GL_FOG_MODE, GL_EXP);
760 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
761 if(GL_SUPPORT(EXT_FOG_COORD)) {
762 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
763 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
767 case WINED3DFOG_EXP2:
768 glFogi(GL_FOG_MODE, GL_EXP2);
769 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
770 if(GL_SUPPORT(EXT_FOG_COORD)) {
771 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
772 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
776 case WINED3DFOG_LINEAR:
777 glFogi(GL_FOG_MODE, GL_LINEAR);
778 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
779 if(GL_SUPPORT(EXT_FOG_COORD)) {
780 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
781 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
785 case WINED3DFOG_NONE: /* Won't happen */
787 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
793 checkGLcall("glEnable GL_FOG");
795 glFogfv(GL_FOG_START, &fogstart);
796 checkGLcall("glFogf(GL_FOG_START, fogstart");
797 TRACE("Fog Start == %f\n", fogstart);
799 glFogfv(GL_FOG_END, &fogend);
800 checkGLcall("glFogf(GL_FOG_END, fogend");
801 TRACE("Fog End == %f\n", fogend);
804 checkGLcall("glDisable GL_FOG");
807 if (GL_SUPPORT(NV_FOG_DISTANCE)) {
808 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
812 static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
814 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
815 /* Set the default alpha blend color */
816 glFogfv(GL_FOG_COLOR, &col[0]);
817 checkGLcall("glFog GL_FOG_COLOR");
820 static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
825 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
826 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
827 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
830 /* TODO: Merge with primitive type + init_materials()!! */
831 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
832 IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)stateblock->wineD3DDevice;
834 WineDirect3DStridedData *diffuse = &device->strided_streams.u.s.diffuse;
835 BOOL isDiffuseSupplied;
837 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
838 * The vertex declaration will call this function if the fixed function pipeline is used.
841 if(isStateDirty(context, STATE_VDECL)) {
845 isDiffuseSupplied = diffuse->lpData || diffuse->VBO;
847 if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) {
848 TRACE("diff %d, amb %d, emis %d, spec %d\n",
849 stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
850 stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
851 stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
852 stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
854 if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
855 if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
856 Parm = GL_AMBIENT_AND_DIFFUSE;
860 } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
862 } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
864 } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
869 /* Nothing changed, return. */
870 if (Parm == context->tracking_parm) return;
873 glDisable(GL_COLOR_MATERIAL);
874 checkGLcall("glDisable GL_COLOR_MATERIAL");
876 glColorMaterial(GL_FRONT_AND_BACK, Parm);
877 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
878 glEnable(GL_COLOR_MATERIAL);
879 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
882 /* Apparently calls to glMaterialfv are ignored for properties we're
883 * tracking with glColorMaterial, so apply those here. */
884 switch (context->tracking_parm) {
885 case GL_AMBIENT_AND_DIFFUSE:
886 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
887 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
888 checkGLcall("glMaterialfv");
892 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
893 checkGLcall("glMaterialfv");
897 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
898 checkGLcall("glMaterialfv");
902 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
903 checkGLcall("glMaterialfv");
907 /* Only change material color if specular is enabled, otherwise it is set to black */
908 if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
909 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
910 checkGLcall("glMaterialfv");
912 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
913 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
914 checkGLcall("glMaterialfv");
919 context->tracking_parm = Parm;
922 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
925 WINED3DLINEPATTERN lp;
927 tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
929 TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
931 if (tmppattern.lp.wRepeatFactor) {
932 glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
933 checkGLcall("glLineStipple(repeat, linepattern)");
934 glEnable(GL_LINE_STIPPLE);
935 checkGLcall("glEnable(GL_LINE_STIPPLE);");
937 glDisable(GL_LINE_STIPPLE);
938 checkGLcall("glDisable(GL_LINE_STIPPLE);");
942 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
948 if (stateblock->renderState[WINED3DRS_ZBIAS]) {
949 tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
950 TRACE("ZBias value %f\n", tmpvalue.f);
951 glPolygonOffset(0, -tmpvalue.f);
952 checkGLcall("glPolygonOffset(0, -Value)");
953 glEnable(GL_POLYGON_OFFSET_FILL);
954 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
955 glEnable(GL_POLYGON_OFFSET_LINE);
956 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
957 glEnable(GL_POLYGON_OFFSET_POINT);
958 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
960 glDisable(GL_POLYGON_OFFSET_FILL);
961 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
962 glDisable(GL_POLYGON_OFFSET_LINE);
963 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
964 glDisable(GL_POLYGON_OFFSET_POINT);
965 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
970 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
971 if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]) {
972 glEnable(GL_NORMALIZE);
973 checkGLcall("glEnable(GL_NORMALIZE);");
975 glDisable(GL_NORMALIZE);
976 checkGLcall("glDisable(GL_NORMALIZE);");
980 static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
986 /* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
987 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
988 TRACE("Set point size to %f\n", tmpvalue.f);
989 glPointSize(tmpvalue.f);
990 checkGLcall("glPointSize(...);");
993 static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
999 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1000 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1001 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, tmpvalue.f);
1002 checkGLcall("glPointParameterfARB(...");
1004 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1005 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f);
1006 checkGLcall("glPointParameterfEXT(...);");
1007 } else if(tmpvalue.f != 1.0) {
1008 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1012 static void state_psizemax(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1018 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1019 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1020 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, tmpvalue.f);
1021 checkGLcall("glPointParameterfARB(...");
1023 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1024 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f);
1025 checkGLcall("glPointParameterfEXT(...);");
1026 } else if(tmpvalue.f != 64.0) {
1027 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1031 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1032 /* TODO: Group this with the viewport */
1034 * POINTSCALEENABLE controls how point size value is treated. If set to
1035 * true, the point size is scaled with respect to height of viewport.
1036 * When set to false point size is in pixels.
1038 * http://msdn.microsoft.com/library/en-us/directx9_c/point_sprites.asp
1041 /* Default values */
1042 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1045 * Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
1046 * This means that OpenGL will clamp really small point sizes to 1.0f.
1047 * To correct for this we need to multiply by the scale factor when sizes
1048 * are less than 1.0f. scale_factor = 1.0f / point_size.
1050 GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
1051 if(pointSize > 0.0f) {
1052 GLfloat scaleFactor;
1054 if(pointSize < 1.0f) {
1055 scaleFactor = pointSize * pointSize;
1060 if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1061 att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) /
1062 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1063 att[1] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_B]) /
1064 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1065 att[2] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_C]) /
1066 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1070 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1071 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1072 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...");
1074 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1075 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1076 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
1078 TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
1082 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1083 DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1085 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1086 Value & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1087 Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1088 Value & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1089 Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1090 glColorMask(Value & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1091 Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1092 Value & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1093 Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1094 checkGLcall("glColorMask(...)");
1096 /* depends on WINED3DRS_COLORWRITEENABLE. */
1097 if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
1098 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
1099 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
1100 ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
1101 stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
1102 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
1103 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1107 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1108 if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1109 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1110 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1112 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1113 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1117 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1118 if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1119 TRACE("Last Pixel Drawing Enabled\n");
1121 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1125 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1129 /* TODO: NV_POINT_SPRITE */
1130 if (!GL_SUPPORT(ARB_POINT_SPRITE)) {
1131 TRACE("Point sprites not supported\n");
1135 if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1141 for (i = 0; i < GL_LIMITS(texture_stages); i++) {
1142 /* Note the WINED3DRS value applies to all textures, but GL has one
1143 * per texture, so apply it now ready to be used!
1145 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1146 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
1147 checkGLcall("glActiveTextureARB");
1149 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1153 glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, val);
1154 checkGLcall((val?"glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)":
1155 "glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE)"));
1159 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1161 http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1162 http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/FixedFunction/Textures/texturewrapping.asp
1163 http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1164 Descussion that ways to turn on WRAPing to solve an opengl conversion problem.
1165 http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1167 so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1170 if(stateblock->renderState[WINED3DRS_WRAP0] ||
1171 stateblock->renderState[WINED3DRS_WRAP1] ||
1172 stateblock->renderState[WINED3DRS_WRAP2] ||
1173 stateblock->renderState[WINED3DRS_WRAP3] ||
1174 stateblock->renderState[WINED3DRS_WRAP4] ||
1175 stateblock->renderState[WINED3DRS_WRAP5] ||
1176 stateblock->renderState[WINED3DRS_WRAP6] ||
1177 stateblock->renderState[WINED3DRS_WRAP7] ||
1178 stateblock->renderState[WINED3DRS_WRAP8] ||
1179 stateblock->renderState[WINED3DRS_WRAP9] ||
1180 stateblock->renderState[WINED3DRS_WRAP10] ||
1181 stateblock->renderState[WINED3DRS_WRAP11] ||
1182 stateblock->renderState[WINED3DRS_WRAP12] ||
1183 stateblock->renderState[WINED3DRS_WRAP13] ||
1184 stateblock->renderState[WINED3DRS_WRAP14] ||
1185 stateblock->renderState[WINED3DRS_WRAP15] ) {
1186 ERR("(WINED3DRS_WRAP0) Texture wraping not yet supported\n");
1190 static void state_multisampleaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1191 if( GL_SUPPORT(ARB_MULTISAMPLE) ) {
1192 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1193 glEnable(GL_MULTISAMPLE_ARB);
1194 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1196 glDisable(GL_MULTISAMPLE_ARB);
1197 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1200 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1201 ERR("Multisample antialiasing not supported by gl\n");
1206 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1207 if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1208 glEnable(GL_SCISSOR_TEST);
1209 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1211 glDisable(GL_SCISSOR_TEST);
1212 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1216 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1222 if(stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] ||
1223 stateblock->renderState[WINED3DRS_DEPTHBIAS]) {
1224 tmpvalue.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1225 glEnable(GL_POLYGON_OFFSET_FILL);
1226 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1227 glPolygonOffset(tmpvalue.f, *((float*)&stateblock->renderState[WINED3DRS_DEPTHBIAS]));
1228 checkGLcall("glPolygonOffset(...)");
1230 glDisable(GL_POLYGON_OFFSET_FILL);
1231 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1235 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1236 if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1237 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1238 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1240 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1241 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1245 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1247 if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1248 ERR(" Stippled Alpha not supported yet.\n");
1251 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1253 if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1254 ERR(" Antialias not supported yet.\n");
1257 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1259 if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1260 ERR("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1263 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1265 if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
1266 ERR("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1269 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1277 if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1278 ERR("(WINED3DRS_PATCHSEGMENTS,%d) not yet implemented\n", tmpvalue.d);
1281 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1283 if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
1284 ERR("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1287 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1289 if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
1290 ERR("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1293 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1295 if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1296 FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1300 static void state_srgbwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1301 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
1302 ERR("Render state WINED3DRS_SRGBWRITEENABLE not yet implemented\n");
1305 static void state_seperateblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1307 if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE])
1308 FIXME("(WINED3DRS_SEPARATEALPHABLENDENABLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]);
1311 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1312 if(stateblock->renderState[WINED3DRS_WRAPU]) {
1313 FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1317 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1318 if(stateblock->renderState[WINED3DRS_WRAPV]) {
1319 FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1323 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1324 if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1325 FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1329 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1330 if(stateblock->renderState[WINED3DRS_ROP2]) {
1331 FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1335 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1336 if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1337 FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1341 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1342 if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1343 FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1347 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1348 if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1349 FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1353 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1354 if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1355 FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1359 static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1360 if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
1361 FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
1365 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1366 if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1367 FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1371 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1372 if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1373 FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1377 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1378 if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1379 FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1383 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1384 if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1385 FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1389 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1390 if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1391 FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1395 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1396 if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1397 FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1401 /* Activates the texture dimension according to the bound D3D texture.
1402 * Does not care for the colorop or correct gl texture unit(when using nvrc)
1403 * Requires the caller to activate the correct unit before
1405 static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock) {
1406 if(stateblock->textures[stage]) {
1407 glDisable(GL_TEXTURE_1D);
1408 checkGLcall("glDisable(GL_TEXTURE_1D)");
1409 switch(stateblock->textureDimensions[stage]) {
1411 glDisable(GL_TEXTURE_3D);
1412 checkGLcall("glDisable(GL_TEXTURE_3D)");
1413 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1414 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1415 glEnable(GL_TEXTURE_2D);
1416 checkGLcall("glEnable(GL_TEXTURE_2D)");
1419 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1420 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1421 glDisable(GL_TEXTURE_2D);
1422 checkGLcall("glDisable(GL_TEXTURE_2D)");
1423 glEnable(GL_TEXTURE_3D);
1424 checkGLcall("glEnable(GL_TEXTURE_3D)");
1426 case GL_TEXTURE_CUBE_MAP_ARB:
1427 glDisable(GL_TEXTURE_2D);
1428 checkGLcall("glDisable(GL_TEXTURE_2D)");
1429 glDisable(GL_TEXTURE_3D);
1430 checkGLcall("glDisable(GL_TEXTURE_3D)");
1431 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
1432 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
1436 glDisable(GL_TEXTURE_2D);
1437 checkGLcall("glDisable(GL_TEXTURE_2D)");
1438 glDisable(GL_TEXTURE_3D);
1439 checkGLcall("glDisable(GL_TEXTURE_3D)");
1440 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1441 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1442 glEnable(GL_TEXTURE_1D);
1443 checkGLcall("glEnable(GL_TEXTURE_1D)");
1444 /* Binding textures is done by samplers. A dummy texture will be bound */
1448 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1449 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1450 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1452 TRACE("Setting color op for stage %d\n", stage);
1454 if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
1455 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1456 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
1460 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
1462 if (mapped_stage != -1) {
1463 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1464 if (mapped_stage >= GL_LIMITS(sampler_stages)) {
1465 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1466 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1467 FIXME("Attempt to enable unsupported stage!\n");
1471 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1472 checkGLcall("glActiveTextureARB");
1473 } else if (stage > 0) {
1474 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1479 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1480 if(stateblock->lowest_disabled_stage > 0) {
1481 glEnable(GL_REGISTER_COMBINERS_NV);
1482 GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, stateblock->lowest_disabled_stage));
1484 glDisable(GL_REGISTER_COMBINERS_NV);
1487 if(stage >= stateblock->lowest_disabled_stage) {
1488 TRACE("Stage disabled\n");
1489 if (mapped_stage != -1) {
1490 /* Disable everything here */
1491 glDisable(GL_TEXTURE_1D);
1492 checkGLcall("glDisable(GL_TEXTURE_1D)");
1493 glDisable(GL_TEXTURE_2D);
1494 checkGLcall("glDisable(GL_TEXTURE_2D)");
1495 glDisable(GL_TEXTURE_3D);
1496 checkGLcall("glDisable(GL_TEXTURE_3D)");
1497 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1498 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1504 /* The sampler will also activate the correct texture dimensions, so no need to do it here
1505 * if the sampler for this stage is dirty
1507 if(!isStateDirty(context, STATE_SAMPLER(stage))) {
1508 if (mapped_stage != -1) activate_dimensions(stage, stateblock);
1511 /* Set the texture combiners */
1512 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1513 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1514 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1515 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1516 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1517 stateblock->textureState[stage][WINED3DTSS_COLORARG0],
1520 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1521 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1522 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1523 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1524 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
1528 static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1529 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1530 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1531 DWORD op, arg1, arg2, arg0;
1533 TRACE("Setting alpha op for stage %d\n", stage);
1534 /* Do not care for enabled / disabled stages, just assign the settigns. colorop disables / enables required stuff */
1535 if (mapped_stage != -1) {
1536 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1537 if (stage >= GL_LIMITS(sampler_stages)) {
1538 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1539 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1540 FIXME("Attempt to enable unsupported stage!\n");
1544 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1545 checkGLcall("glActiveTextureARB");
1546 } else if (stage > 0) {
1547 /* We can't do anything here */
1548 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1553 op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
1554 arg1 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG1];
1555 arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
1556 arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
1558 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 &&
1559 stateblock->textures[0] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) {
1560 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
1562 if(surf->CKeyFlags & DDSD_CKSRCBLT &&
1563 getFormatDescEntry(surf->resource.format)->alphaMask == 0x00000000) {
1565 /* Color keying needs to pass alpha values from the texture through to have the alpha test work properly.
1566 * On the other hand applications can still use texture combiners apparently. This code takes care that apps
1567 * cannot remove the texture's alpha channel entirely.
1569 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires D3DTOP_MODULATE to work
1570 * on color keyed surfaces.
1572 * What to do with multitexturing? So far no app has been found that uses color keying with multitexturing
1574 if(op == WINED3DTOP_DISABLE) op = WINED3DTOP_SELECTARG1;
1575 if(op == WINED3DTOP_SELECTARG1) arg1 = WINED3DTA_TEXTURE;
1576 else if(op == WINED3DTOP_SELECTARG2) arg2 = WINED3DTA_TEXTURE;
1580 TRACE("Setting alpha op for stage %d\n", stage);
1581 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1582 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1583 op, arg1, arg2, arg0,
1586 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1587 op, arg1, arg2, arg0);
1591 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1592 DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
1594 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1595 if(texUnit >= GL_LIMITS(sampler_stages)) {
1598 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stateblock->wineD3DDevice->texUnitMap[texUnit]));
1599 checkGLcall("glActiveTextureARB");
1600 } else if (texUnit > 0) {
1601 /* We can't do anything here */
1602 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1606 set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
1607 stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
1608 (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU);
1612 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd);
1614 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1615 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1616 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1618 if (mapped_stage == -1) {
1619 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
1623 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1624 if(stage >= GL_LIMITS(sampler_stages)) {
1627 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1628 checkGLcall("glActiveTextureARB");
1629 } else if (stage > 0) {
1630 /* We can't do anything here */
1631 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1635 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
1637 * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
1638 * one flag, you can still specify an index value, which the system uses to
1639 * determine the texture wrapping mode.
1640 * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
1641 * means use the vertex position (camera-space) as the input texture coordinates
1642 * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
1643 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
1644 * to the TEXCOORDINDEX value
1648 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
1650 switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) {
1651 case WINED3DTSS_TCI_PASSTHRU:
1652 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
1653 glDisable(GL_TEXTURE_GEN_S);
1654 glDisable(GL_TEXTURE_GEN_T);
1655 glDisable(GL_TEXTURE_GEN_R);
1656 glDisable(GL_TEXTURE_GEN_Q);
1657 checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R,Q)");
1660 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
1661 /* CameraSpacePosition means use the vertex position, transformed to camera space,
1662 * as the input texture coordinates for this stage's texture transformation. This
1663 * equates roughly to EYE_LINEAR
1666 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1667 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1668 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1669 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1670 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
1672 glMatrixMode(GL_MODELVIEW);
1675 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1676 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1677 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1678 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1681 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
1682 glEnable(GL_TEXTURE_GEN_S);
1683 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1684 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1685 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1686 glEnable(GL_TEXTURE_GEN_T);
1687 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1688 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1689 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1690 glEnable(GL_TEXTURE_GEN_R);
1691 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1692 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1693 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1697 case WINED3DTSS_TCI_CAMERASPACENORMAL:
1699 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1700 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1701 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1702 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1703 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1704 TRACE("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane\n");
1706 glMatrixMode(GL_MODELVIEW);
1709 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1710 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1711 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1712 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1715 glEnable(GL_TEXTURE_GEN_S);
1716 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1717 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1718 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1719 glEnable(GL_TEXTURE_GEN_T);
1720 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1721 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1722 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1723 glEnable(GL_TEXTURE_GEN_R);
1724 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1725 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1726 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1731 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
1733 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1734 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1735 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1736 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1737 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1738 TRACE("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane\n");
1740 glMatrixMode(GL_MODELVIEW);
1743 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1744 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1745 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1746 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1749 glEnable(GL_TEXTURE_GEN_S);
1750 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1751 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1752 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1753 glEnable(GL_TEXTURE_GEN_T);
1754 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1755 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1756 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1757 glEnable(GL_TEXTURE_GEN_R);
1758 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1759 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1760 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1765 /* Unhandled types: */
1768 /* ? disable GL_TEXTURE_GEN_n ? */
1769 glDisable(GL_TEXTURE_GEN_S);
1770 glDisable(GL_TEXTURE_GEN_T);
1771 glDisable(GL_TEXTURE_GEN_R);
1772 glDisable(GL_TEXTURE_GEN_Q);
1773 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %x\n", stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
1777 /* Update the texture matrix */
1778 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
1779 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
1782 if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
1783 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
1784 * source. Call loadVertexData directly because there is no need to reparse the vertex declaration
1785 * and do all the things linked to it
1786 * TODO: Tidy that up to reload only the arrays of the changed unit
1788 loadVertexData(stateblock, &stateblock->wineD3DDevice->strided_streams);
1792 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1793 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1799 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
1800 if(tmpvalue.f != 0.0) {
1801 ERR("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
1805 static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1806 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1812 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
1813 if(tmpvalue.f != 0.0) {
1814 ERR("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
1818 static void tex_resultarg(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1819 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1821 if(stage >= GL_LIMITS(texture_stages)) {
1825 if(stateblock->textureState[stage][WINED3DTSS_RESULTARG] != WINED3DTA_CURRENT) {
1826 ERR("WINED3DTSS_RESULTARG not supported yet\n");
1830 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1831 DWORD sampler = state - STATE_SAMPLER(0);
1832 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
1838 TRACE("Sampler: %d\n", sampler);
1839 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
1840 * only has to bind textures and set the per texture states
1843 if (mapped_stage == -1) {
1844 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
1848 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1849 if(sampler >= GL_LIMITS(sampler_stages)) {
1852 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1853 checkGLcall("glActiveTextureARB");
1854 } else if (sampler > 0) {
1855 /* We can't do anything here */
1856 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1860 if(stateblock->textures[sampler]) {
1861 BOOL texIsPow2 = FALSE;
1863 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
1864 * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
1865 * scaling is reapplied or removed, the texture matrix has to be reapplied
1867 if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) {
1868 if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) {
1869 if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 ||
1870 ((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) {
1873 } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
1874 if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->pow2scalingFactor != 1.0) {
1879 if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
1880 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
1881 context->lastWasPow2Texture[sampler] = texIsPow2;
1885 IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) stateblock->textures[sampler]);
1886 IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
1888 if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
1889 tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
1890 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
1891 GL_TEXTURE_LOD_BIAS_EXT,
1893 checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
1896 if (stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader &&
1897 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1898 /* Using a pixel shader? Verify the sampler types */
1900 /* Make sure that the texture dimensions are enabled. I don't have to disable the other
1901 * dimensions because the shader knows from which texture type to sample from. For the sake of
1902 * debugging all dimensions could be enabled and a texture with some ugly pink bound to the unused
1903 * dimensions. This should make wrong sampling sources visible :-)
1905 glEnable(stateblock->textureDimensions[sampler]);
1906 checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
1907 } else if(sampler < stateblock->lowest_disabled_stage) {
1908 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
1909 activate_dimensions(sampler, stateblock);
1912 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
1913 /* If color keying is enabled update the alpha test, it depends on the existence
1914 * of a color key in stage 0
1916 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
1919 } else if(sampler < GL_LIMITS(texture_stages)) {
1920 if(sampler < stateblock->lowest_disabled_stage) {
1921 /* TODO: What should I do with pixel shaders here ??? */
1922 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
1923 activate_dimensions(sampler, stateblock);
1925 } /* Otherwise tex_colorop disables the stage */
1926 glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
1927 checkGLcall("glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
1931 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1932 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
1934 /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
1935 * has an update pending
1937 if(isStateDirty(context, STATE_VDECL) ||
1938 isStateDirty(context, STATE_PIXELSHADER)) {
1942 device->shader_backend->shader_load_constants((IWineD3DDevice *) device,
1943 stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function,
1944 stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function);
1947 static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1948 BOOL use_ps = stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function != NULL;
1949 BOOL use_vs = stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL;
1953 if(!context->last_was_pshader) {
1954 /* Former draw without a pixel shader, some samplers
1955 * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
1956 * make sure to enable them
1958 for(i=0; i < MAX_SAMPLERS; i++) {
1959 if(!isStateDirty(context, STATE_SAMPLER(i))) {
1960 sampler(STATE_SAMPLER(i), stateblock, context);
1964 /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
1965 * if a different texture was bound. I don't have to do anything.
1969 /* Compile and bind the shader */
1970 IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
1972 /* Disabled the pixel shader - color ops weren't applied
1973 * while it was enabled, so re-apply them.
1975 for(i=0; i < MAX_TEXTURES; i++) {
1976 if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
1977 tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
1982 if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) {
1983 stateblock->wineD3DDevice->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_ps, use_vs);
1985 if(!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vs || use_ps)) {
1986 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
1990 context->last_was_pshader = use_ps;
1993 static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1994 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1996 if(stateblock->pixelShader && stage != 0 &&
1997 ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->needsbumpmat == stage) {
1998 /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
2001 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
2002 !isStateDirty(context, STATE_PIXELSHADER)) {
2003 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
2008 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2009 /* This function is called by transform_view below if the view matrix was changed too
2011 * Deliberately no check if the vertex declaration is dirty because the vdecl state
2012 * does not always update the world matrix, only on a switch between transformed
2013 * and untrannsformed draws. It *may* happen that the world matrix is set 2 times during one
2014 * draw, but that should be rather rare and cheaper in total.
2016 glMatrixMode(GL_MODELVIEW);
2017 checkGLcall("glMatrixMode");
2019 if(context->last_was_rhw) {
2021 checkGLcall("glLoadIdentity()");
2023 /* In the general case, the view matrix is the identity matrix */
2024 if (stateblock->wineD3DDevice->view_ident) {
2025 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2026 checkGLcall("glLoadMatrixf");
2028 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2029 checkGLcall("glLoadMatrixf");
2030 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2031 checkGLcall("glMultMatrixf");
2036 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2039 /* If we are changing the View matrix, reset the light and clipping planes to the new view
2040 * NOTE: We have to reset the positions even if the light/plane is not currently
2041 * enabled, since the call to enable it will not reset the position.
2042 * NOTE2: Apparently texture transforms do NOT need reapplying
2045 PLIGHTINFOEL *light = NULL;
2047 glMatrixMode(GL_MODELVIEW);
2048 checkGLcall("glMatrixMode(GL_MODELVIEW)");
2049 glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2050 checkGLcall("glLoadMatrixf(...)");
2052 /* Reset lights. TODO: Call light apply func */
2053 for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) {
2054 light = stateblock->activeLights[k];
2055 if(!light) continue;
2056 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
2057 checkGLcall("glLightfv posn");
2058 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
2059 checkGLcall("glLightfv dirn");
2062 /* Reset Clipping Planes if clipping is enabled. TODO: Call clipplane apply func */
2063 for (k = 0; k < GL_LIMITS(clipplanes); k++) {
2064 glClipPlane(GL_CLIP_PLANE0 + k, stateblock->clipplane[k]);
2065 checkGLcall("glClipPlane");
2068 if(context->last_was_rhw) {
2070 checkGLcall("glLoadIdentity()");
2071 /* No need to update the world matrix, the identity is fine */
2075 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
2076 * No need to do it here if the state is scheduled for update.
2078 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
2079 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2083 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2084 WARN("World matrix 1 - 255 not supported yet\n");
2087 static const GLfloat invymat[16] = {
2088 1.0f, 0.0f, 0.0f, 0.0f,
2089 0.0f, -1.0f, 0.0f, 0.0f,
2090 0.0f, 0.0f, 1.0f, 0.0f,
2091 0.0f, 0.0f, 0.0f, 1.0f};
2093 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2094 glMatrixMode(GL_PROJECTION);
2095 checkGLcall("glMatrixMode(GL_PROJECTION)");
2097 checkGLcall("glLoadIdentity");
2099 if(context->last_was_rhw) {
2100 double X, Y, height, width, minZ, maxZ;
2102 X = stateblock->viewport.X;
2103 Y = stateblock->viewport.Y;
2104 height = stateblock->viewport.Height;
2105 width = stateblock->viewport.Width;
2106 minZ = stateblock->viewport.MinZ;
2107 maxZ = stateblock->viewport.MaxZ;
2109 if(!stateblock->wineD3DDevice->untransformed) {
2110 /* Transformed vertices are supposed to bypass the whole transform pipeline including
2111 * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
2112 * suppress depth clipping. This can be done because it is an orthogonal projection and
2113 * the Z coordinate does not affect the size of the primitives
2115 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
2116 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
2118 /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
2119 * trick above because this would mess up transformed and untransformed Z order. Pass the z position
2120 * unmodified to opengl.
2122 * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
2123 * replacement shader.
2125 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
2126 glOrtho(X, X + width, Y + height, Y, 1.0, -1.0);
2128 checkGLcall("glOrtho");
2130 /* Window Coord 0 is the middle of the first pixel, so translate by 3/8 pixels */
2131 glTranslatef(0.375, 0.375, 0);
2132 checkGLcall("glTranslatef(0.375, 0.375, 0)");
2133 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2134 * render everything upside down when rendering offscreen. */
2135 if (stateblock->wineD3DDevice->render_offscreen) {
2136 glMultMatrixf(invymat);
2137 checkGLcall("glMultMatrixf(invymat)");
2140 /* The rule is that the window coordinate 0 does not correspond to the
2141 beginning of the first pixel, but the center of the first pixel.
2142 As a consequence if you want to correctly draw one line exactly from
2143 the left to the right end of the viewport (with all matrices set to
2144 be identity), the x coords of both ends of the line would be not
2145 -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
2147 glTranslatef(0.9 / stateblock->viewport.Width, -0.9 / stateblock->viewport.Height, 0);
2148 checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");
2150 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2151 * render everything upside down when rendering offscreen. */
2152 if (stateblock->wineD3DDevice->render_offscreen) {
2153 glMultMatrixf(invymat);
2154 checkGLcall("glMultMatrixf(invymat)");
2156 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
2157 checkGLcall("glLoadMatrixf");
2161 /* This should match any arrays loaded in loadVertexData.
2162 * stateblock impl is required for GL_SUPPORT
2163 * TODO: Only load / unload arrays if we have to.
2165 static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
2168 glDisableClientState(GL_VERTEX_ARRAY);
2169 glDisableClientState(GL_NORMAL_ARRAY);
2170 glDisableClientState(GL_COLOR_ARRAY);
2171 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2172 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2174 for (texture_idx = 0; texture_idx < GL_LIMITS(textures); ++texture_idx) {
2175 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2176 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2180 /* This should match any arrays loaded in loadNumberedArrays
2181 * TODO: Only load / unload arrays if we have to.
2183 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
2184 /* disable any attribs (this is the same for both GLSL and ARB modes) */
2188 /* Leave all the attribs disabled */
2189 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
2190 /* MESA does not support it right not */
2191 if (glGetError() != GL_NO_ERROR)
2193 for (i = 0; i < maxAttribs; ++i) {
2194 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2195 checkGLcall("glDisableVertexAttribArrayARB(reg);");
2199 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
2200 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2202 UINT *offset = stateblock->streamOffset;
2204 /* Default to no instancing */
2205 stateblock->wineD3DDevice->instancedDraw = FALSE;
2207 for (i = 0; i < MAX_ATTRIBS; i++) {
2209 if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
2212 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
2213 if(stateblock->streamFlags[strided->u.input[i].streamNo] & WINED3DSTREAMSOURCE_INSTANCEDATA) {
2214 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2215 stateblock->wineD3DDevice->instancedDraw = TRUE;
2219 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
2221 if(strided->u.input[i].dwStride) {
2222 if(curVBO != strided->u.input[i].VBO) {
2223 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
2224 checkGLcall("glBindBufferARB");
2225 curVBO = strided->u.input[i].VBO;
2227 GL_EXTCALL(glVertexAttribPointerARB(i,
2228 WINED3D_ATR_SIZE(strided->u.input[i].dwType),
2229 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
2230 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
2231 strided->u.input[i].dwStride,
2232 strided->u.input[i].lpData + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + offset[strided->u.input[i].streamNo]) );
2233 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
2235 /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
2236 * set up the attribute statically. But we have to figure out the system memory address.
2238 BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo];
2239 if(strided->u.input[i].VBO) {
2240 IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
2241 ptr += (long) vb->resource.allocatedMemory;
2243 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2245 switch(strided->u.input[i].dwType) {
2246 case WINED3DDECLTYPE_FLOAT1:
2247 GL_EXTCALL(glVertexAttrib1fvARB(i, (float *) ptr));
2249 case WINED3DDECLTYPE_FLOAT2:
2250 GL_EXTCALL(glVertexAttrib2fvARB(i, (float *) ptr));
2252 case WINED3DDECLTYPE_FLOAT3:
2253 GL_EXTCALL(glVertexAttrib3fvARB(i, (float *) ptr));
2255 case WINED3DDECLTYPE_FLOAT4:
2256 GL_EXTCALL(glVertexAttrib4fvARB(i, (float *) ptr));
2259 case WINED3DDECLTYPE_UBYTE4:
2260 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2262 case WINED3DDECLTYPE_UBYTE4N:
2263 case WINED3DDECLTYPE_D3DCOLOR:
2264 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2267 case WINED3DDECLTYPE_SHORT2:
2268 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2270 case WINED3DDECLTYPE_SHORT4:
2271 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2274 case WINED3DDECLTYPE_SHORT2N:
2276 GLshort s[4] = {((short *) ptr)[0], ((short *) ptr)[1], 0, 1};
2277 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
2280 case WINED3DDECLTYPE_USHORT2N:
2282 GLushort s[4] = {((unsigned short *) ptr)[0], ((unsigned short *) ptr)[1], 0, 1};
2283 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
2286 case WINED3DDECLTYPE_SHORT4N:
2287 GL_EXTCALL(glVertexAttrib4NsvARB(i, (GLshort *) ptr));
2289 case WINED3DDECLTYPE_USHORT4N:
2290 GL_EXTCALL(glVertexAttrib4NusvARB(i, (GLushort *) ptr));
2293 case WINED3DDECLTYPE_UDEC3:
2294 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
2295 /*glVertexAttrib3usvARB(i, (GLushort *) ptr); Does not exist */
2297 case WINED3DDECLTYPE_DEC3N:
2298 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
2299 /*glVertexAttrib3NusvARB(i, (GLushort *) ptr); Does not exist */
2302 case WINED3DDECLTYPE_FLOAT16_2:
2303 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
2304 * byte float according to the IEEE standard
2306 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
2308 case WINED3DDECLTYPE_FLOAT16_4:
2309 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
2312 case WINED3DDECLTYPE_UNUSED:
2314 ERR("Unexpected declaration in stride 0 attributes\n");
2322 /* Used from 2 different functions, and too big to justify making it inlined */
2323 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
2324 unsigned int textureNo = 0;
2325 unsigned int texture_idx = 0;
2326 UINT *offset = stateblock->streamOffset;
2327 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2329 TRACE("Using fast vertex array code\n");
2331 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
2332 stateblock->wineD3DDevice->instancedDraw = FALSE;
2334 /* Blend Data ---------------------------------------------- */
2335 if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
2336 (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
2339 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2342 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
2343 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
2346 TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2347 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2348 /* FIXME("TODO\n");*/
2349 /* Note dwType == float3 or float4 == 2 or 3 */
2352 /* with this on, the normals appear to be being modified,
2353 but the vertices aren't being translated as they should be
2354 Maybe the world matrix aren't being setup properly? */
2355 glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1);
2359 VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
2360 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
2361 sd->u.s.blendWeights.dwStride,
2362 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
2364 if(curVBO != sd->u.s.blendWeights.VBO) {
2365 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
2366 checkGLcall("glBindBufferARB");
2367 curVBO = sd->u.s.blendWeights.VBO;
2370 GL_EXTCALL(glWeightPointerARB)(
2371 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2372 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2373 sd->u.s.blendWeights.dwStride,
2374 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2376 checkGLcall("glWeightPointerARB");
2378 if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
2379 static BOOL showfixme = TRUE;
2381 FIXME("blendMatrixIndices support\n");
2386 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2387 /* FIXME("TODO\n");*/
2390 GL_EXTCALL(glVertexWeightPointerEXT)(
2391 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2392 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2393 sd->u.s.blendWeights.dwStride,
2394 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
2395 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
2396 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2397 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2401 /* TODO: support blends in drawStridedSlow
2402 * No need to write a FIXME here, this is done after the general vertex decl decoding
2404 WARN("unsupported blending in openGl\n");
2407 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2408 #if 0 /* TODO: Vertex blending */
2409 glDisable(GL_VERTEX_BLEND_ARB);
2411 TRACE("ARB_VERTEX_BLEND\n");
2412 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2413 TRACE(" EXT_VERTEX_WEIGHTING\n");
2414 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2415 checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2420 #if 0 /* FOG ----------------------------------------------*/
2421 if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
2423 if (GL_SUPPORT(EXT_FOG_COORD) {
2424 glEnableClientState(GL_FOG_COORDINATE_EXT);
2425 (GL_EXTCALL)(FogCoordPointerEXT)(
2426 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
2427 sd->u.s.fog.dwStride,
2428 sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
2430 /* don't bother falling back to 'slow' as we don't support software FOG yet. */
2431 /* FIXME: fixme once */
2432 TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
2435 if (GL_SUPPRT(EXT_FOR_COORD) {
2436 /* make sure fog is disabled */
2437 glDisableClientState(GL_FOG_COORDINATE_EXT);
2442 #if 0 /* tangents ----------------------------------------------*/
2443 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO ||
2444 sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2446 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2447 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO) {
2448 glEnable(GL_TANGENT_ARRAY_EXT);
2449 (GL_EXTCALL)(TangentPointerEXT)(
2450 WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
2451 sd->u.s.tangent.dwStride,
2452 sd->u.s.tangent.lpData + stateblock->loadBaseVertexIndex * sd->u.s.tangent.dwStride);
2454 glDisable(GL_TANGENT_ARRAY_EXT);
2456 if (sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2457 glEnable(GL_BINORMAL_ARRAY_EXT);
2458 (GL_EXTCALL)(BinormalPointerEXT)(
2459 WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
2460 sd->u.s.binormal.dwStride,
2461 sd->u.s.binormal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.binormal.dwStride);
2463 glDisable(GL_BINORMAL_ARRAY_EXT);
2467 /* don't bother falling back to 'slow' as we don't support software tangents and binormals yet . */
2468 /* FIXME: fixme once */
2469 TRACE("Hardware support for tangents and binormals is not avaiable, tangents and binormals disabled.\n");
2472 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2473 /* make sure fog is disabled */
2474 glDisable(GL_TANGENT_ARRAY_EXT);
2475 glDisable(GL_BINORMAL_ARRAY_EXT);
2480 /* Point Size ----------------------------------------------*/
2481 if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {
2483 /* no such functionality in the fixed function GL pipeline */
2484 TRACE("Cannot change ptSize here in openGl\n");
2485 /* TODO: Implement this function in using shaders if they are available */
2489 /* Vertex Pointers -----------------------------------------*/
2490 if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
2491 /* Note dwType == float3 or float4 == 2 or 3 */
2492 VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
2493 sd->u.s.position.dwStride,
2494 sd->u.s.position.dwType + 1,
2495 sd->u.s.position.lpData));
2497 if(curVBO != sd->u.s.position.VBO) {
2498 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
2499 checkGLcall("glBindBufferARB");
2500 curVBO = sd->u.s.position.VBO;
2503 /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
2504 handling for rhw mode should not impact screen position whereas in GL it does.
2505 This may result in very slightly distored textures in rhw mode, but
2506 a very minimal different. There's always the other option of
2507 fixing the view matrix to prevent w from having any effect
2509 This only applies to user pointer sources, in VBOs the vertices are fixed up
2511 if(sd->u.s.position.VBO == 0) {
2512 glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
2513 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2514 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2517 WINED3D_ATR_SIZE(sd->u.s.position.dwType),
2518 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2519 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2521 checkGLcall("glVertexPointer(...)");
2522 glEnableClientState(GL_VERTEX_ARRAY);
2523 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
2526 glDisableClientState(GL_VERTEX_ARRAY);
2527 checkGLcall("glDisableClientState(GL_VERTEX_ARRAY)");
2530 /* Normals -------------------------------------------------*/
2531 if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
2532 /* Note dwType == float3 or float4 == 2 or 3 */
2533 VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
2534 sd->u.s.normal.dwStride,
2535 sd->u.s.normal.lpData));
2536 if(curVBO != sd->u.s.normal.VBO) {
2537 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
2538 checkGLcall("glBindBufferARB");
2539 curVBO = sd->u.s.normal.VBO;
2542 WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
2543 sd->u.s.normal.dwStride,
2544 sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]);
2545 checkGLcall("glNormalPointer(...)");
2546 glEnableClientState(GL_NORMAL_ARRAY);
2547 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
2550 glDisableClientState(GL_NORMAL_ARRAY);
2551 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
2552 glNormal3f(0, 0, 1);
2553 checkGLcall("glNormal3f(0, 0, 1)");
2556 /* Diffuse Colour --------------------------------------------*/
2557 /* WARNING: Data here MUST be in RGBA format, so cannot */
2558 /* go directly into fast mode from app pgm, because */
2559 /* directx requires data in BGRA format. */
2560 /* currently fixupVertices swizels the format, but this isn't */
2561 /* very practical when using VBOS */
2562 /* NOTE: Unless we write a vertex shader to swizel the colour */
2563 /* , or the user doesn't care and wants the speed advantage */
2565 if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
2566 /* Note dwType == float3 or float4 == 2 or 3 */
2567 VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2568 sd->u.s.diffuse.dwStride,
2569 sd->u.s.diffuse.lpData));
2571 if(curVBO != sd->u.s.diffuse.VBO) {
2572 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
2573 checkGLcall("glBindBufferARB");
2574 curVBO = sd->u.s.diffuse.VBO;
2576 glColorPointer(4, GL_UNSIGNED_BYTE,
2577 sd->u.s.diffuse.dwStride,
2578 sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
2579 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
2580 glEnableClientState(GL_COLOR_ARRAY);
2581 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
2584 glDisableClientState(GL_COLOR_ARRAY);
2585 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
2586 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2587 checkGLcall("glColor4f(1, 1, 1, 1)");
2590 /* Specular Colour ------------------------------------------*/
2591 if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
2592 TRACE("setting specular colour\n");
2593 /* Note dwType == float3 or float4 == 2 or 3 */
2594 VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2595 sd->u.s.specular.dwStride,
2596 sd->u.s.specular.lpData));
2597 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2598 if(curVBO != sd->u.s.specular.VBO) {
2599 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
2600 checkGLcall("glBindBufferARB");
2601 curVBO = sd->u.s.specular.VBO;
2603 GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
2604 sd->u.s.specular.dwStride,
2605 sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
2606 vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
2607 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2608 vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2611 /* Missing specular color is not critical, no warnings */
2612 VTRACE(("Specular colour is not supported in this GL implementation\n"));
2616 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2618 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2619 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2620 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
2621 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
2624 /* Missing specular color is not critical, no warnings */
2625 VTRACE(("Specular colour is not supported in this GL implementation\n"));
2629 /* Texture coords -------------------------------------------*/
2631 for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
2632 /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
2633 /* Abort if we don't support the extension. */
2634 if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
2635 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2639 if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) {
2640 /* Select the correct texture stage */
2641 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2644 if (stateblock->textures[textureNo] != NULL) {
2645 int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
2647 if (coordIdx >= MAX_TEXTURES) {
2648 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
2649 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2650 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2652 } else if (sd->u.s.texCoords[coordIdx].lpData == NULL && sd->u.s.texCoords[coordIdx].VBO == 0) {
2653 VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n"));
2654 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2655 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2658 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
2659 textureNo, texture_idx, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
2660 if(curVBO != sd->u.s.texCoords[coordIdx].VBO) {
2661 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
2662 checkGLcall("glBindBufferARB");
2663 curVBO = sd->u.s.texCoords[coordIdx].VBO;
2665 /* The coords to supply depend completely on the fvf / vertex shader */
2667 WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
2668 WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
2669 sd->u.s.texCoords[coordIdx].dwStride,
2670 sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
2671 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2673 } else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2674 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2675 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2677 if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) ++texture_idx;
2679 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2680 for (textureNo = texture_idx; textureNo < GL_LIMITS(textures); ++textureNo) {
2681 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo));
2682 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2683 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2688 inline void drawPrimitiveTraceDataLocations(
2689 WineDirect3DVertexStridedData *dataLocations) {
2691 /* Dump out what parts we have supplied */
2692 TRACE("Strided Data:\n");
2693 TRACE_STRIDED((dataLocations), position);
2694 TRACE_STRIDED((dataLocations), blendWeights);
2695 TRACE_STRIDED((dataLocations), blendMatrixIndices);
2696 TRACE_STRIDED((dataLocations), normal);
2697 TRACE_STRIDED((dataLocations), pSize);
2698 TRACE_STRIDED((dataLocations), diffuse);
2699 TRACE_STRIDED((dataLocations), specular);
2700 TRACE_STRIDED((dataLocations), texCoords[0]);
2701 TRACE_STRIDED((dataLocations), texCoords[1]);
2702 TRACE_STRIDED((dataLocations), texCoords[2]);
2703 TRACE_STRIDED((dataLocations), texCoords[3]);
2704 TRACE_STRIDED((dataLocations), texCoords[4]);
2705 TRACE_STRIDED((dataLocations), texCoords[5]);
2706 TRACE_STRIDED((dataLocations), texCoords[6]);
2707 TRACE_STRIDED((dataLocations), texCoords[7]);
2708 TRACE_STRIDED((dataLocations), position2);
2709 TRACE_STRIDED((dataLocations), normal2);
2710 TRACE_STRIDED((dataLocations), tangent);
2711 TRACE_STRIDED((dataLocations), binormal);
2712 TRACE_STRIDED((dataLocations), tessFactor);
2713 TRACE_STRIDED((dataLocations), fog);
2714 TRACE_STRIDED((dataLocations), depth);
2715 TRACE_STRIDED((dataLocations), sample);
2720 /* Helper for vertexdeclaration() */
2721 static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVertexShaderFunction, WineD3DContext *context) {
2722 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2724 WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
2726 if(device->up_strided) {
2727 /* Note: this is a ddraw fixed-function code path */
2728 TRACE("================ Strided Input ===================\n");
2729 memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
2732 drawPrimitiveTraceDataLocations(dataLocations);
2734 } else if (stateblock->vertexDecl || stateblock->vertexShader) {
2735 /* Note: This is a fixed function or shader codepath.
2736 * This means it must handle both types of strided data.
2737 * Shaders must go through here to zero the strided data, even if they
2738 * don't set any declaration at all
2740 TRACE("================ Vertex Declaration ===================\n");
2741 memset(dataLocations, 0, sizeof(*dataLocations));
2743 if (stateblock->vertexDecl) {
2744 primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device, useVertexShaderFunction,
2745 dataLocations, &fixup);
2748 /* Note: This codepath is not reachable from d3d9 (see fvf->decl9 conversion)
2749 * It is reachable through d3d8, but only for fixed-function.
2750 * It will not work properly for shaders.
2752 TRACE("================ FVF ===================\n");
2753 memset(dataLocations, 0, sizeof(*dataLocations));
2754 primitiveConvertToStridedData((IWineD3DDevice *) device, dataLocations, &fixup);
2756 drawPrimitiveTraceDataLocations(dataLocations);
2760 /* Unload the old arrays before loading the new ones to get old junk out */
2761 if(context->numberedArraysLoaded) {
2762 unloadNumberedArrays(stateblock);
2763 context->numberedArraysLoaded = FALSE;
2765 if(context->namedArraysLoaded) {
2766 unloadVertexData(stateblock);
2767 context->namedArraysLoaded = FALSE;
2770 if(useVertexShaderFunction) {
2771 TRACE("Loading numbered arrays\n");
2772 loadNumberedArrays(stateblock, dataLocations);
2773 device->useDrawStridedSlow = FALSE;
2774 context->numberedArraysLoaded = TRUE;
2776 (dataLocations->u.s.pSize.lpData == NULL &&
2777 dataLocations->u.s.diffuse.lpData == NULL &&
2778 dataLocations->u.s.specular.lpData == NULL)) {
2779 /* Load the vertex data using named arrays */
2780 TRACE("Loading vertex data\n");
2781 loadVertexData(stateblock, dataLocations);
2782 device->useDrawStridedSlow = FALSE;
2783 context->namedArraysLoaded = TRUE;
2785 TRACE("Not loading vertex data\n");
2786 device->useDrawStridedSlow = TRUE;
2789 /* Generate some fixme's if unsupported functionality is being used */
2790 #define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
2791 /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
2792 if (!useVertexShaderFunction &&
2793 stateblock->renderState[WINED3DRS_VERTEXBLEND] &&
2794 (BUFFER_OR_DATA(blendMatrixIndices) || BUFFER_OR_DATA(blendWeights))) {
2795 FIXME("Vertex Blending is not implemented yet %p %p\n",dataLocations->u.s.blendWeights.lpData,dataLocations->u.s.blendWeights.lpData);
2796 /* TODO: Implement it using GL_ARB_vertex_blend or software emulation in drawStridedSlow */
2798 if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
2799 FIXME("Tweening is only valid with vertex shaders\n");
2801 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tangent) || BUFFER_OR_DATA(binormal))) {
2802 FIXME("Tangent and binormal bump mapping is only valid with vertex shaders\n");
2804 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
2805 FIXME("Extended attributes are only valid with vertex shaders\n");
2807 #undef BUFFER_OR_DATA
2810 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2811 BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
2812 BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
2813 && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
2815 /* Some stuff is in the device until we have per context tracking */
2816 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2817 BOOL wasrhw = context->last_was_rhw;
2819 /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
2820 * here simply check whether a shader was set, or the user disabled shaders
2822 if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
2823 ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
2824 useVertexShaderFunction = TRUE;
2826 if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog != context->last_was_foggy_shader) {
2829 } else if(context->last_was_foggy_shader) {
2833 handleStreams(stateblock, useVertexShaderFunction, context);
2835 /* Do I have to use ? TRUE : FALSE ? Or can I rely on 15==15 being equal to TRUE(=1)? */
2836 transformed = ((device->strided_streams.u.s.position.lpData != NULL ||
2837 device->strided_streams.u.s.position.VBO != 0) &&
2838 device->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
2840 if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
2844 /* Reapply lighting if it is not scheduled for reapplication already */
2845 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
2846 state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
2849 if (!useVertexShaderFunction && transformed) {
2850 context->last_was_rhw = TRUE;
2853 /* Untransformed, so relies on the view and projection matrices */
2854 context->last_was_rhw = FALSE;
2855 /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
2856 device->untransformed = TRUE;
2858 /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
2859 * Not needed as long as only hw shaders are supported
2862 /* This sets the shader output position correction constants.
2863 * TODO: Move to the viewport state
2865 if (useVertexShaderFunction) {
2866 device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
2870 /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
2871 * off this function will be called again anyway to make sure they're properly set
2873 if(!useVertexShaderFunction) {
2874 /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
2875 * or transformed / untransformed was switched
2877 if(wasrhw != context->last_was_rhw &&
2878 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
2879 !isStateDirty(context, STATE_VIEWPORT)) {
2880 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
2882 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
2885 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
2886 * this check will fail and the matrix not applied again. This is OK because a simple
2887 * world matrix change reapplies the matrix - These checks here are only to satisfy the
2888 * needs of the vertex declaration.
2890 * World and view matrix go into the same gl matrix, so only apply them when neither is
2893 if(transformed != wasrhw &&
2894 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
2895 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
2896 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2899 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
2900 state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
2903 /* We compile the shader here because we need the vertex declaration
2904 * in order to determine if we need to do any swizzling for D3DCOLOR
2905 * registers. If the shader is already compiled this call will do nothing. */
2906 IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
2909 /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
2912 if (!isStateDirty(context, STATE_PIXELSHADER)) {
2913 device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
2915 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
2916 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
2920 context->last_was_vshader = useVertexShaderFunction;
2923 state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
2927 static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2928 glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
2929 checkGLcall("glDepthRange");
2930 /* Note: GL requires lower left, DirectX supplies upper left */
2931 /* TODO: replace usage of renderTarget with context management */
2932 glViewport(stateblock->viewport.X,
2933 (((IWineD3DSurfaceImpl *)stateblock->wineD3DDevice->render_targets[0])->currentDesc.Height - (stateblock->viewport.Y + stateblock->viewport.Height)),
2934 stateblock->viewport.Width, stateblock->viewport.Height);
2936 checkGLcall("glViewport");
2938 stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
2939 stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
2940 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
2941 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
2946 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2947 UINT Index = state - STATE_ACTIVELIGHT(0);
2948 PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
2951 glDisable(GL_LIGHT0 + Index);
2952 checkGLcall("glDisable(GL_LIGHT0 + Index)");
2955 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
2957 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
2958 glMatrixMode(GL_MODELVIEW);
2960 glLoadMatrixf((float *)&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2963 colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
2964 colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
2965 colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
2966 colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
2967 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
2968 checkGLcall("glLightfv");
2971 colRGBA[0] = lightInfo->OriginalParms.Specular.r;
2972 colRGBA[1] = lightInfo->OriginalParms.Specular.g;
2973 colRGBA[2] = lightInfo->OriginalParms.Specular.b;
2974 colRGBA[3] = lightInfo->OriginalParms.Specular.a;
2975 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
2976 checkGLcall("glLightfv");
2979 colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
2980 colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
2981 colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
2982 colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
2983 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
2984 checkGLcall("glLightfv");
2986 if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
2987 quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
2989 quad_att = 0; /* 0 or MAX? (0 seems to be ok) */
2992 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
2993 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
2994 * Attenuation0 to NaN and crashes in the gl lib
2997 switch (lightInfo->OriginalParms.Type) {
2998 case WINED3DLIGHT_POINT:
3000 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
3001 checkGLcall("glLightfv");
3002 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3003 checkGLcall("glLightf");
3004 /* Attenuation - Are these right? guessing... */
3005 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
3006 checkGLcall("glLightf");
3007 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
3008 checkGLcall("glLightf");
3009 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3010 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3011 checkGLcall("glLightf");
3015 case WINED3DLIGHT_SPOT:
3017 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
3018 checkGLcall("glLightfv");
3020 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
3021 checkGLcall("glLightfv");
3022 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
3023 checkGLcall("glLightf");
3024 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3025 checkGLcall("glLightf");
3026 /* Attenuation - Are these right? guessing... */
3027 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
3028 checkGLcall("glLightf");
3029 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
3030 checkGLcall("glLightf");
3031 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3032 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3033 checkGLcall("glLightf");
3037 case WINED3DLIGHT_DIRECTIONAL:
3039 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
3040 checkGLcall("glLightfv");
3041 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3042 checkGLcall("glLightf");
3043 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
3044 checkGLcall("glLightf");
3048 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
3051 /* Restore the modelview matrix */
3054 glEnable(GL_LIGHT0 + Index);
3055 checkGLcall("glEnable(GL_LIGHT0 + Index)");
3061 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3062 IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) stateblock->wineD3DDevice->swapchains[0];
3063 RECT *pRect = &stateblock->scissorRect;
3067 GetClientRect(swapchain->win_handle, &windowRect);
3068 /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
3069 * Warning2: Even in windowed mode the coords are relative to the window, not the screen
3071 winHeight = windowRect.bottom - windowRect.top;
3072 TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - winHeight,
3073 pRect->right - pRect->left, pRect->bottom - pRect->top);
3074 glScissor(pRect->left, winHeight - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
3075 checkGLcall("glScissor");
3078 static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3079 if(GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
3080 if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
3081 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
3083 IWineD3DIndexBufferImpl *ib = (IWineD3DIndexBufferImpl *) stateblock->pIndexData;
3084 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->vbo));
3089 const struct StateEntry StateTable[] =
3091 /* State name representative, apply function */
3092 { /* 0, Undefined */ 0, state_undefined },
3093 { /* 1, WINED3DRS_TEXTUREHANDLE */ 0 /* Handled in ddraw */, state_undefined },
3094 { /* 2, WINED3DRS_ANTIALIAS */ STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias },
3095 { /* 3, WINED3DRS_TEXTUREADDRESS */ 0 /* Handled in ddraw */, state_undefined },
3096 { /* 4, WINED3DRS_TEXTUREPERSPECTIVE */ STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective },
3097 { /* 5, WINED3DRS_WRAPU */ STATE_RENDER(WINED3DRS_WRAPU), state_wrapu },
3098 { /* 6, WINED3DRS_WRAPV */ STATE_RENDER(WINED3DRS_WRAPV), state_wrapv },
3099 { /* 7, WINED3DRS_ZENABLE */ STATE_RENDER(WINED3DRS_ZENABLE), state_zenable },
3100 { /* 8, WINED3DRS_FILLMODE */ STATE_RENDER(WINED3DRS_FILLMODE), state_fillmode },
3101 { /* 9, WINED3DRS_SHADEMODE */ STATE_RENDER(WINED3DRS_SHADEMODE), state_shademode },
3102 { /* 10, WINED3DRS_LINEPATTERN */ STATE_RENDER(WINED3DRS_LINEPATTERN), state_linepattern },
3103 { /* 11, WINED3DRS_MONOENABLE */ STATE_RENDER(WINED3DRS_MONOENABLE), state_monoenable },
3104 { /* 12, WINED3DRS_ROP2 */ STATE_RENDER(WINED3DRS_ROP2), state_rop2 },
3105 { /* 13, WINED3DRS_PLANEMASK */ STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask },
3106 { /* 14, WINED3DRS_ZWRITEENABLE */ STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable },
3107 { /* 15, WINED3DRS_ALPHATESTENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3108 { /* 16, WINED3DRS_LASTPIXEL */ STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel },
3109 { /* 17, WINED3DRS_TEXTUREMAG */ 0 /* Handled in ddraw */, state_undefined },
3110 { /* 18, WINED3DRS_TEXTUREMIN */ 0 /* Handled in ddraw */, state_undefined },
3111 { /* 19, WINED3DRS_SRCBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3112 { /* 20, WINED3DRS_DESTBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3113 { /* 21, WINED3DRS_TEXTUREMAPBLEND */ 0 /* Handled in ddraw */, state_undefined },
3114 { /* 22, WINED3DRS_CULLMODE */ STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode },
3115 { /* 23, WINED3DRS_ZFUNC */ STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc },
3116 { /* 24, WINED3DRS_ALPHAREF */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3117 { /* 25, WINED3DRS_ALPHAFUNC */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3118 { /* 26, WINED3DRS_DITHERENABLE */ STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable },
3119 { /* 27, WINED3DRS_ALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3120 { /* 28, WINED3DRS_FOGENABLE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3121 { /* 29, WINED3DRS_SPECULARENABLE */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable},
3122 { /* 30, WINED3DRS_ZVISIBLE */ 0 /* Not supported according to the msdn */, state_nogl },
3123 { /* 31, WINED3DRS_SUBPIXEL */ STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel },
3124 { /* 32, WINED3DRS_SUBPIXELX */ STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx },
3125 { /* 33, WINED3DRS_STIPPLEDALPHA */ STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha },
3126 { /* 34, WINED3DRS_FOGCOLOR */ STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor },
3127 { /* 35, WINED3DRS_FOGTABLEMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3128 { /* 36, WINED3DRS_FOGSTART */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3129 { /* 37, WINED3DRS_FOGEND */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3130 { /* 38, WINED3DRS_FOGDENSITY */ STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity },
3131 { /* 39, WINED3DRS_STIPPLEENABLE */ STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable },
3132 { /* 40, WINED3DRS_EDGEANTIALIAS */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3133 { /* 41, WINED3DRS_COLORKEYENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3134 { /* 42, undefined */ 0, state_undefined },
3135 { /* 43, WINED3DRS_BORDERCOLOR */ STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor },
3136 { /* 44, WINED3DRS_TEXTUREADDRESSU */ 0, /* Handled in ddraw */ state_undefined },
3137 { /* 45, WINED3DRS_TEXTUREADDRESSV */ 0, /* Handled in ddraw */ state_undefined },
3138 { /* 46, WINED3DRS_MIPMAPLODBIAS */ STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias },
3139 { /* 47, WINED3DRS_ZBIAS */ STATE_RENDER(WINED3DRS_ZBIAS), state_zbias },
3140 { /* 48, WINED3DRS_RANGEFOGENABLE */ 0, state_nogl },
3141 { /* 49, WINED3DRS_ANISOTROPY */ STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy },
3142 { /* 50, WINED3DRS_FLUSHBATCH */ STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch },
3143 { /* 51, WINED3DRS_TRANSLUCENTSORTINDEPENDENT */ STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi },
3144 { /* 52, WINED3DRS_STENCILENABLE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3145 { /* 53, WINED3DRS_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3146 { /* 54, WINED3DRS_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3147 { /* 55, WINED3DRS_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3148 { /* 56, WINED3DRS_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3149 { /* 57, WINED3DRS_STENCILREF */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3150 { /* 58, WINED3DRS_STENCILMASK */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3151 { /* 59, WINED3DRS_STENCILWRITEMASK */ STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite },
3152 { /* 60, WINED3DRS_TEXTUREFACTOR */ STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor },
3153 { /* 61, Undefined */ 0, state_undefined },
3154 { /* 62, Undefined */ 0, state_undefined },
3155 { /* 63, Undefined */ 0, state_undefined },
3156 { /* 64, WINED3DRS_STIPPLEPATTERN00 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3157 { /* 65, WINED3DRS_STIPPLEPATTERN01 */ 0 /* Obsolete, should he handled by ddraw */, state_undefined },
3158 { /* 66, WINED3DRS_STIPPLEPATTERN02 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3159 { /* 67, WINED3DRS_STIPPLEPATTERN03 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3160 { /* 68, WINED3DRS_STIPPLEPATTERN04 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3161 { /* 69, WINED3DRS_STIPPLEPATTERN05 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3162 { /* 70, WINED3DRS_STIPPLEPATTERN06 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3163 { /* 71, WINED3DRS_STIPPLEPATTERN07 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3164 { /* 72, WINED3DRS_STIPPLEPATTERN08 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3165 { /* 73, WINED3DRS_STIPPLEPATTERN09 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3166 { /* 74, WINED3DRS_STIPPLEPATTERN10 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3167 { /* 75, WINED3DRS_STIPPLEPATTERN11 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3168 { /* 76, WINED3DRS_STIPPLEPATTERN12 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3169 { /* 77, WINED3DRS_STIPPLEPATTERN13 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3170 { /* 78, WINED3DRS_STIPPLEPATTERN14 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3171 { /* 79, WINED3DRS_STIPPLEPATTERN15 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3172 { /* 80, WINED3DRS_STIPPLEPATTERN16 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3173 { /* 81, WINED3DRS_STIPPLEPATTERN17 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3174 { /* 82, WINED3DRS_STIPPLEPATTERN18 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3175 { /* 83, WINED3DRS_STIPPLEPATTERN19 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3176 { /* 84, WINED3DRS_STIPPLEPATTERN20 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3177 { /* 85, WINED3DRS_STIPPLEPATTERN21 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3178 { /* 86, WINED3DRS_STIPPLEPATTERN22 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3179 { /* 87, WINED3DRS_STIPPLEPATTERN23 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3180 { /* 88, WINED3DRS_STIPPLEPATTERN24 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3181 { /* 89, WINED3DRS_STIPPLEPATTERN25 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3182 { /* 90, WINED3DRS_STIPPLEPATTERN26 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3183 { /* 91, WINED3DRS_STIPPLEPATTERN27 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3184 { /* 92, WINED3DRS_STIPPLEPATTERN28 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3185 { /* 93, WINED3DRS_STIPPLEPATTERN29 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3186 { /* 94, WINED3DRS_STIPPLEPATTERN30 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3187 { /* 95, WINED3DRS_STIPPLEPATTERN31 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3188 { /* 96, Undefined */ 0, state_undefined },
3189 { /* 97, Undefined */ 0, state_undefined },
3190 { /* 98, Undefined */ 0, state_undefined },
3191 { /* 99, Undefined */ 0, state_undefined },
3192 { /*100, Undefined */ 0, state_undefined },
3193 { /*101, Undefined */ 0, state_undefined },
3194 { /*102, Undefined */ 0, state_undefined },
3195 { /*103, Undefined */ 0, state_undefined },
3196 { /*104, Undefined */ 0, state_undefined },
3197 { /*105, Undefined */ 0, state_undefined },
3198 { /*106, Undefined */ 0, state_undefined },
3199 { /*107, Undefined */ 0, state_undefined },
3200 { /*108, Undefined */ 0, state_undefined },
3201 { /*109, Undefined */ 0, state_undefined },
3202 { /*110, Undefined */ 0, state_undefined },
3203 { /*111, Undefined */ 0, state_undefined },
3204 { /*112, Undefined */ 0, state_undefined },
3205 { /*113, Undefined */ 0, state_undefined },
3206 { /*114, Undefined */ 0, state_undefined },
3207 { /*115, Undefined */ 0, state_undefined },
3208 { /*116, Undefined */ 0, state_undefined },
3209 { /*117, Undefined */ 0, state_undefined },
3210 { /*118, Undefined */ 0, state_undefined },
3211 { /*119, Undefined */ 0, state_undefined },
3212 { /*120, Undefined */ 0, state_undefined },
3213 { /*121, Undefined */ 0, state_undefined },
3214 { /*122, Undefined */ 0, state_undefined },
3215 { /*123, Undefined */ 0, state_undefined },
3216 { /*124, Undefined */ 0, state_undefined },
3217 { /*125, Undefined */ 0, state_undefined },
3218 { /*126, Undefined */ 0, state_undefined },
3219 { /*127, Undefined */ 0, state_undefined },
3221 { /*128, WINED3DRS_WRAP0 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3222 { /*129, WINED3DRS_WRAP1 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3223 { /*130, WINED3DRS_WRAP2 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3224 { /*131, WINED3DRS_WRAP3 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3225 { /*132, WINED3DRS_WRAP4 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3226 { /*133, WINED3DRS_WRAP5 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3227 { /*134, WINED3DRS_WRAP6 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3228 { /*135, WINED3DRS_WRAP7 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3229 { /*136, WINED3DRS_CLIPPING */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3230 { /*137, WINED3DRS_LIGHTING */ STATE_RENDER(WINED3DRS_LIGHTING), state_lighting },
3231 { /*138, WINED3DRS_EXTENTS */ STATE_RENDER(WINED3DRS_EXTENTS), state_extents },
3232 { /*139, WINED3DRS_AMBIENT */ STATE_RENDER(WINED3DRS_AMBIENT), state_ambient },
3233 { /*140, WINED3DRS_FOGVERTEXMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3234 { /*141, WINED3DRS_COLORVERTEX */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3235 { /*142, WINED3DRS_LOCALVIEWER */ STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer },
3236 { /*143, WINED3DRS_NORMALIZENORMALS */ STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize },
3237 { /*144, WINED3DRS_COLORKEYBLENDENABLE */ STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend },
3238 { /*145, WINED3DRS_DIFFUSEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3239 { /*146, WINED3DRS_SPECULARMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3240 { /*147, WINED3DRS_AMBIENTMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3241 { /*148, WINED3DRS_EMISSIVEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3242 { /*149, Undefined */ 0, state_undefined },
3243 { /*150, Undefined */ 0, state_undefined },
3244 { /*151, WINED3DRS_VERTEXBLEND */ 0, state_nogl },
3245 { /*152, WINED3DRS_CLIPPLANEENABLE */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3246 { /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING */ 0, state_nogl },
3247 { /*154, WINED3DRS_POINTSIZE */ STATE_RENDER(WINED3DRS_POINTSIZE), state_psize },
3248 { /*155, WINED3DRS_POINTSIZE_MIN */ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin },
3249 { /*156, WINED3DRS_POINTSPRITEENABLE */ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite },
3250 { /*157, WINED3DRS_POINTSCALEENABLE */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3251 { /*158, WINED3DRS_POINTSCALE_A */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3252 { /*159, WINED3DRS_POINTSCALE_B */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3253 { /*160, WINED3DRS_POINTSCALE_C */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3254 { /*161, WINED3DRS_MULTISAMPLEANTIALIAS */ STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_multisampleaa },
3255 { /*162, WINED3DRS_MULTISAMPLEMASK */ STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask },
3256 { /*163, WINED3DRS_PATCHEDGESTYLE */ STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), state_patchedgestyle},
3257 { /*164, WINED3DRS_PATCHSEGMENTS */ STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments },
3258 { /*165, WINED3DRS_DEBUGMONITORTOKEN */ STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_nogl },
3259 { /*166, WINED3DRS_POINTSIZE_MAX */ STATE_RENDER(WINED3DRS_POINTSIZE_MAX), state_psizemax },
3260 { /*167, WINED3DRS_INDEXEDVERTEXBLENDENABLE */ 0, state_nogl },
3261 { /*168, WINED3DRS_COLORWRITEENABLE */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3262 { /*169, Undefined */ 0, state_undefined },
3263 { /*170, WINED3DRS_TWEENFACTOR */ 0, state_nogl },
3264 { /*171, WINED3DRS_BLENDOP */ STATE_RENDER(WINED3DRS_BLENDOP), state_blendop },
3265 { /*172, WINED3DRS_POSITIONDEGREE */ STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree},
3266 { /*173, WINED3DRS_NORMALDEGREE */ STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree },
3267 /*172, WINED3DRS_POSITIONORDER */ /* Value assigned to 2 state names */
3268 /*173, WINED3DRS_NORMALORDER */ /* Value assigned to 2 state names */
3269 { /*174, WINED3DRS_SCISSORTESTENABLE */ STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor },
3270 { /*175, WINED3DRS_SLOPESCALEDEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3271 { /*176, WINED3DRS_ANTIALIASEDLINEENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3272 { /*177, undefined */ 0, state_undefined },
3273 { /*178, WINED3DRS_MINTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3274 { /*179, WINED3DRS_MAXTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3275 { /*180, WINED3DRS_ADAPTIVETESS_X */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3276 { /*181, WINED3DRS_ADAPTIVETESS_Y */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3277 { /*182, WINED3DRS_ADAPTIVETESS_Z */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3278 { /*183, WINED3DRS_ADAPTIVETESS_W */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3279 { /*184, WINED3DRS_ENABLEADAPTIVETESSELLATION */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3280 { /*185, WINED3DRS_TWOSIDEDSTENCILMODE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3281 { /*186, WINED3DRS_CCW_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3282 { /*187, WINED3DRS_CCW_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3283 { /*188, WINED3DRS_CCW_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3284 { /*189, WINED3DRS_CCW_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3285 { /*190, WINED3DRS_COLORWRITEENABLE1 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3286 { /*191, WINED3DRS_COLORWRITEENABLE2 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3287 { /*192, WINED3DRS_COLORWRITEENABLE3 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3288 { /*193, WINED3DRS_BLENDFACTOR */ STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor },
3289 { /*194, WINED3DRS_SRGBWRITEENABLE */ STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), state_srgbwrite },
3290 { /*195, WINED3DRS_DEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3291 { /*196, undefined */ 0, state_undefined },
3292 { /*197, undefined */ 0, state_undefined },
3293 { /*198, WINED3DRS_WRAP8 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3294 { /*199, WINED3DRS_WRAP9 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3295 { /*200, WINED3DRS_WRAP10 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3296 { /*201, WINED3DRS_WRAP11 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3297 { /*202, WINED3DRS_WRAP12 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3298 { /*203, WINED3DRS_WRAP13 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3299 { /*204, WINED3DRS_WRAP14 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3300 { /*205, WINED3DRS_WRAP15 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3301 { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3302 { /*207, WINED3DRS_SRCBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3303 { /*208, WINED3DRS_DESTBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3304 { /*209, WINED3DRS_BLENDOPALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3305 /* Texture stage states */
3306 { /*0, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3307 { /*0, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3308 { /*0, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3309 { /*0, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3310 { /*0, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3311 { /*0, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3312 { /*0, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3313 { /*0, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3314 { /*0, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3315 { /*0, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3316 { /*0, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3317 { /*0, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3318 { /*0, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3319 { /*0, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3320 { /*0, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3321 { /*0, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3322 { /*0, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3323 { /*0, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3324 { /*0, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3325 { /*0, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3326 { /*0, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3327 { /*0, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3328 { /*0, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3329 { /*0, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3330 { /*0, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3331 { /*0, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3332 { /*0, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3333 { /*0, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), tex_resultarg },
3334 { /*0, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3335 { /*0, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3336 { /*0, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3337 { /*0, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3339 { /*1, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3340 { /*1, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3341 { /*1, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3342 { /*1, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3343 { /*1, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3344 { /*1, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3345 { /*1, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3346 { /*1, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3347 { /*1, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3348 { /*1, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3349 { /*1, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3350 { /*1, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3351 { /*1, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3352 { /*1, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3353 { /*1, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3354 { /*1, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3355 { /*1, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3356 { /*1, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3357 { /*1, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3358 { /*1, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3359 { /*1, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3360 { /*1, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3361 { /*1, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3362 { /*1, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3363 { /*1, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3364 { /*1, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3365 { /*1, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3366 { /*1, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), tex_resultarg },
3367 { /*1, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3368 { /*1, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3369 { /*1, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3370 { /*1, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3372 { /*2, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3373 { /*2, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3374 { /*2, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3375 { /*2, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3376 { /*2, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3377 { /*2, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3378 { /*2, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3379 { /*2, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3380 { /*2, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3381 { /*2, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3382 { /*2, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3383 { /*2, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3384 { /*2, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3385 { /*2, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3386 { /*2, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3387 { /*2, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3388 { /*2, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3389 { /*2, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3390 { /*2, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3391 { /*2, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3392 { /*2, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3393 { /*2, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3394 { /*2, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3395 { /*2, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3396 { /*2, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3397 { /*2, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3398 { /*2, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3399 { /*2, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), tex_resultarg },
3400 { /*2, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3401 { /*2, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3402 { /*2, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3403 { /*2, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3405 { /*3, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3406 { /*3, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3407 { /*3, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3408 { /*3, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3409 { /*3, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3410 { /*3, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3411 { /*3, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3412 { /*3, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3413 { /*3, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3414 { /*3, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3415 { /*3, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3416 { /*3, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3417 { /*3, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3418 { /*3, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3419 { /*3, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3420 { /*3, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3421 { /*3, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3422 { /*3, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3423 { /*3, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3424 { /*3, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3425 { /*3, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3426 { /*3, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3427 { /*3, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3428 { /*3, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3429 { /*3, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3430 { /*3, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3431 { /*3, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3432 { /*3, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), tex_resultarg },
3433 { /*3, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3434 { /*3, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3435 { /*3, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3436 { /*3, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3438 { /*4, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3439 { /*4, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3440 { /*4, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3441 { /*4, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3442 { /*4, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3443 { /*4, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3444 { /*4, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3445 { /*4, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3446 { /*4, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3447 { /*4, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3448 { /*4, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3449 { /*4, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3450 { /*4, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3451 { /*4, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3452 { /*4, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3453 { /*4, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3454 { /*4, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3455 { /*4, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3456 { /*4, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3457 { /*4, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3458 { /*4, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3459 { /*4, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3460 { /*4, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3461 { /*4, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3462 { /*4, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3463 { /*4, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3464 { /*4, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3465 { /*4, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), tex_resultarg },
3466 { /*4, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3467 { /*4, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3468 { /*4, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3469 { /*4, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3471 { /*5, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3472 { /*5, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3473 { /*5, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3474 { /*5, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3475 { /*5, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3476 { /*5, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3477 { /*5, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3478 { /*5, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3479 { /*5, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3480 { /*5, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3481 { /*5, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3482 { /*5, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3483 { /*5, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3484 { /*5, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3485 { /*5, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3486 { /*5, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3487 { /*5, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3488 { /*5, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3489 { /*5, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3490 { /*5, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3491 { /*5, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3492 { /*5, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3493 { /*5, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3494 { /*5, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3495 { /*5, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3496 { /*5, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3497 { /*5, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3498 { /*5, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), tex_resultarg },
3499 { /*5, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3500 { /*5, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3501 { /*5, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3502 { /*5, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3504 { /*6, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3505 { /*6, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3506 { /*6, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3507 { /*6, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3508 { /*6, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3509 { /*6, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3510 { /*6, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3511 { /*6, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3512 { /*6, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3513 { /*6, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3514 { /*6, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3515 { /*6, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3516 { /*6, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3517 { /*6, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3518 { /*6, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3519 { /*6, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3520 { /*6, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3521 { /*6, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3522 { /*6, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3523 { /*6, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3524 { /*6, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3525 { /*6, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3526 { /*6, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3527 { /*6, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3528 { /*6, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3529 { /*6, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3530 { /*6, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3531 { /*6, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), tex_resultarg },
3532 { /*6, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3533 { /*6, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3534 { /*6, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3535 { /*6, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3537 { /*7, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3538 { /*7, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3539 { /*7, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3540 { /*7, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3541 { /*7, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3542 { /*7, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3543 { /*7, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3544 { /*7, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3545 { /*7, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3546 { /*7, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3547 { /*7, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3548 { /*7, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3549 { /*7, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3550 { /*7, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3551 { /*7, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3552 { /*7, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3553 { /*7, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3554 { /*7, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3555 { /*7, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3556 { /*7, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3557 { /*7, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3558 { /*7, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3559 { /*7, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3560 { /*7, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3561 { /*7, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3562 { /*7, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3563 { /*7, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3564 { /*7, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), tex_resultarg },
3565 { /*7, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3566 { /*7, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3567 { /*7, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3568 { /*7, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3569 /* Sampler states */
3570 { /* 0, Sampler 0 */ STATE_SAMPLER(0), sampler },
3571 { /* 1, Sampler 1 */ STATE_SAMPLER(1), sampler },
3572 { /* 2, Sampler 2 */ STATE_SAMPLER(2), sampler },
3573 { /* 3, Sampler 3 */ STATE_SAMPLER(3), sampler },
3574 { /* 4, Sampler 3 */ STATE_SAMPLER(4), sampler },
3575 { /* 5, Sampler 5 */ STATE_SAMPLER(5), sampler },
3576 { /* 6, Sampler 6 */ STATE_SAMPLER(6), sampler },
3577 { /* 7, Sampler 7 */ STATE_SAMPLER(7), sampler },
3578 { /* 8, Sampler 8 */ STATE_SAMPLER(8), sampler },
3579 { /* 9, Sampler 9 */ STATE_SAMPLER(9), sampler },
3580 { /*10, Sampler 10 */ STATE_SAMPLER(10), sampler },
3581 { /*11, Sampler 11 */ STATE_SAMPLER(11), sampler },
3582 { /*12, Sampler 12 */ STATE_SAMPLER(12), sampler },
3583 { /*13, Sampler 13 */ STATE_SAMPLER(13), sampler },
3584 { /*14, Sampler 14 */ STATE_SAMPLER(14), sampler },
3585 { /*15, Sampler 15 */ STATE_SAMPLER(15), sampler },
3587 { /* , Pixel Shader */ STATE_PIXELSHADER, pixelshader },
3588 /* Transform states follow */
3589 { /* 1, undefined */ 0, state_undefined },
3590 { /* 2, WINED3DTS_VIEW */ STATE_TRANSFORM(WINED3DTS_VIEW), transform_view },
3591 { /* 3, WINED3DTS_PROJECTION */ STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection},
3592 { /* 4, undefined */ 0, state_undefined },
3593 { /* 5, undefined */ 0, state_undefined },
3594 { /* 6, undefined */ 0, state_undefined },
3595 { /* 7, undefined */ 0, state_undefined },
3596 { /* 8, undefined */ 0, state_undefined },
3597 { /* 9, undefined */ 0, state_undefined },
3598 { /* 10, undefined */ 0, state_undefined },
3599 { /* 11, undefined */ 0, state_undefined },
3600 { /* 12, undefined */ 0, state_undefined },
3601 { /* 13, undefined */ 0, state_undefined },
3602 { /* 14, undefined */ 0, state_undefined },
3603 { /* 15, undefined */ 0, state_undefined },
3604 { /* 16, WINED3DTS_TEXTURE0 */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3605 { /* 17, WINED3DTS_TEXTURE1 */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3606 { /* 18, WINED3DTS_TEXTURE2 */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3607 { /* 19, WINED3DTS_TEXTURE3 */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3608 { /* 20, WINED3DTS_TEXTURE4 */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3609 { /* 21, WINED3DTS_TEXTURE5 */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3610 { /* 22, WINED3DTS_TEXTURE6 */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3611 { /* 23, WINED3DTS_TEXTURE7 */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3612 /* A huge gap between TEXTURE7 and WORLDMATRIX(0) :-( But entries are needed to catch then if a broken app sets them */
3613 { /* 24, undefined */ 0, state_undefined },
3614 { /* 25, undefined */ 0, state_undefined },
3615 { /* 26, undefined */ 0, state_undefined },
3616 { /* 27, undefined */ 0, state_undefined },
3617 { /* 28, undefined */ 0, state_undefined },
3618 { /* 29, undefined */ 0, state_undefined },
3619 { /* 30, undefined */ 0, state_undefined },
3620 { /* 31, undefined */ 0, state_undefined },
3621 { /* 32, undefined */ 0, state_undefined },
3622 { /* 33, undefined */ 0, state_undefined },
3623 { /* 34, undefined */ 0, state_undefined },
3624 { /* 35, undefined */ 0, state_undefined },
3625 { /* 36, undefined */ 0, state_undefined },
3626 { /* 37, undefined */ 0, state_undefined },
3627 { /* 38, undefined */ 0, state_undefined },
3628 { /* 39, undefined */ 0, state_undefined },
3629 { /* 40, undefined */ 0, state_undefined },
3630 { /* 41, undefined */ 0, state_undefined },
3631 { /* 42, undefined */ 0, state_undefined },
3632 { /* 43, undefined */ 0, state_undefined },
3633 { /* 44, undefined */ 0, state_undefined },
3634 { /* 45, undefined */ 0, state_undefined },
3635 { /* 46, undefined */ 0, state_undefined },
3636 { /* 47, undefined */ 0, state_undefined },
3637 { /* 48, undefined */ 0, state_undefined },
3638 { /* 49, undefined */ 0, state_undefined },
3639 { /* 50, undefined */ 0, state_undefined },
3640 { /* 51, undefined */ 0, state_undefined },
3641 { /* 52, undefined */ 0, state_undefined },
3642 { /* 53, undefined */ 0, state_undefined },
3643 { /* 54, undefined */ 0, state_undefined },
3644 { /* 55, undefined */ 0, state_undefined },
3645 { /* 56, undefined */ 0, state_undefined },
3646 { /* 57, undefined */ 0, state_undefined },
3647 { /* 58, undefined */ 0, state_undefined },
3648 { /* 59, undefined */ 0, state_undefined },
3649 { /* 60, undefined */ 0, state_undefined },
3650 { /* 61, undefined */ 0, state_undefined },
3651 { /* 62, undefined */ 0, state_undefined },
3652 { /* 63, undefined */ 0, state_undefined },
3653 { /* 64, undefined */ 0, state_undefined },
3654 { /* 65, undefined */ 0, state_undefined },
3655 { /* 66, undefined */ 0, state_undefined },
3656 { /* 67, undefined */ 0, state_undefined },
3657 { /* 68, undefined */ 0, state_undefined },
3658 { /* 69, undefined */ 0, state_undefined },
3659 { /* 70, undefined */ 0, state_undefined },
3660 { /* 71, undefined */ 0, state_undefined },
3661 { /* 72, undefined */ 0, state_undefined },
3662 { /* 73, undefined */ 0, state_undefined },
3663 { /* 74, undefined */ 0, state_undefined },
3664 { /* 75, undefined */ 0, state_undefined },
3665 { /* 76, undefined */ 0, state_undefined },
3666 { /* 77, undefined */ 0, state_undefined },
3667 { /* 78, undefined */ 0, state_undefined },
3668 { /* 79, undefined */ 0, state_undefined },
3669 { /* 80, undefined */ 0, state_undefined },
3670 { /* 81, undefined */ 0, state_undefined },
3671 { /* 82, undefined */ 0, state_undefined },
3672 { /* 83, undefined */ 0, state_undefined },
3673 { /* 84, undefined */ 0, state_undefined },
3674 { /* 85, undefined */ 0, state_undefined },
3675 { /* 86, undefined */ 0, state_undefined },
3676 { /* 87, undefined */ 0, state_undefined },
3677 { /* 88, undefined */ 0, state_undefined },
3678 { /* 89, undefined */ 0, state_undefined },
3679 { /* 90, undefined */ 0, state_undefined },
3680 { /* 91, undefined */ 0, state_undefined },
3681 { /* 92, undefined */ 0, state_undefined },
3682 { /* 93, undefined */ 0, state_undefined },
3683 { /* 94, undefined */ 0, state_undefined },
3684 { /* 95, undefined */ 0, state_undefined },
3685 { /* 96, undefined */ 0, state_undefined },
3686 { /* 97, undefined */ 0, state_undefined },
3687 { /* 98, undefined */ 0, state_undefined },
3688 { /* 99, undefined */ 0, state_undefined },
3689 { /*100, undefined */ 0, state_undefined },
3690 { /*101, undefined */ 0, state_undefined },
3691 { /*102, undefined */ 0, state_undefined },
3692 { /*103, undefined */ 0, state_undefined },
3693 { /*104, undefined */ 0, state_undefined },
3694 { /*105, undefined */ 0, state_undefined },
3695 { /*106, undefined */ 0, state_undefined },
3696 { /*107, undefined */ 0, state_undefined },
3697 { /*108, undefined */ 0, state_undefined },
3698 { /*109, undefined */ 0, state_undefined },
3699 { /*110, undefined */ 0, state_undefined },
3700 { /*111, undefined */ 0, state_undefined },
3701 { /*112, undefined */ 0, state_undefined },
3702 { /*113, undefined */ 0, state_undefined },
3703 { /*114, undefined */ 0, state_undefined },
3704 { /*115, undefined */ 0, state_undefined },
3705 { /*116, undefined */ 0, state_undefined },
3706 { /*117, undefined */ 0, state_undefined },
3707 { /*118, undefined */ 0, state_undefined },
3708 { /*119, undefined */ 0, state_undefined },
3709 { /*120, undefined */ 0, state_undefined },
3710 { /*121, undefined */ 0, state_undefined },
3711 { /*122, undefined */ 0, state_undefined },
3712 { /*123, undefined */ 0, state_undefined },
3713 { /*124, undefined */ 0, state_undefined },
3714 { /*125, undefined */ 0, state_undefined },
3715 { /*126, undefined */ 0, state_undefined },
3716 { /*127, undefined */ 0, state_undefined },
3717 { /*128, undefined */ 0, state_undefined },
3718 { /*129, undefined */ 0, state_undefined },
3719 { /*130, undefined */ 0, state_undefined },
3720 { /*131, undefined */ 0, state_undefined },
3721 { /*132, undefined */ 0, state_undefined },
3722 { /*133, undefined */ 0, state_undefined },
3723 { /*134, undefined */ 0, state_undefined },
3724 { /*135, undefined */ 0, state_undefined },
3725 { /*136, undefined */ 0, state_undefined },
3726 { /*137, undefined */ 0, state_undefined },
3727 { /*138, undefined */ 0, state_undefined },
3728 { /*139, undefined */ 0, state_undefined },
3729 { /*140, undefined */ 0, state_undefined },
3730 { /*141, undefined */ 0, state_undefined },
3731 { /*142, undefined */ 0, state_undefined },
3732 { /*143, undefined */ 0, state_undefined },
3733 { /*144, undefined */ 0, state_undefined },
3734 { /*145, undefined */ 0, state_undefined },
3735 { /*146, undefined */ 0, state_undefined },
3736 { /*147, undefined */ 0, state_undefined },
3737 { /*148, undefined */ 0, state_undefined },
3738 { /*149, undefined */ 0, state_undefined },
3739 { /*150, undefined */ 0, state_undefined },
3740 { /*151, undefined */ 0, state_undefined },
3741 { /*152, undefined */ 0, state_undefined },
3742 { /*153, undefined */ 0, state_undefined },
3743 { /*154, undefined */ 0, state_undefined },
3744 { /*155, undefined */ 0, state_undefined },
3745 { /*156, undefined */ 0, state_undefined },
3746 { /*157, undefined */ 0, state_undefined },
3747 { /*158, undefined */ 0, state_undefined },
3748 { /*159, undefined */ 0, state_undefined },
3749 { /*160, undefined */ 0, state_undefined },
3750 { /*161, undefined */ 0, state_undefined },
3751 { /*162, undefined */ 0, state_undefined },
3752 { /*163, undefined */ 0, state_undefined },
3753 { /*164, undefined */ 0, state_undefined },
3754 { /*165, undefined */ 0, state_undefined },
3755 { /*166, undefined */ 0, state_undefined },
3756 { /*167, undefined */ 0, state_undefined },
3757 { /*168, undefined */ 0, state_undefined },
3758 { /*169, undefined */ 0, state_undefined },
3759 { /*170, undefined */ 0, state_undefined },
3760 { /*171, undefined */ 0, state_undefined },
3761 { /*172, undefined */ 0, state_undefined },
3762 { /*173, undefined */ 0, state_undefined },
3763 { /*174, undefined */ 0, state_undefined },
3764 { /*175, undefined */ 0, state_undefined },
3765 { /*176, undefined */ 0, state_undefined },
3766 { /*177, undefined */ 0, state_undefined },
3767 { /*178, undefined */ 0, state_undefined },
3768 { /*179, undefined */ 0, state_undefined },
3769 { /*180, undefined */ 0, state_undefined },
3770 { /*181, undefined */ 0, state_undefined },
3771 { /*182, undefined */ 0, state_undefined },
3772 { /*183, undefined */ 0, state_undefined },
3773 { /*184, undefined */ 0, state_undefined },
3774 { /*185, undefined */ 0, state_undefined },
3775 { /*186, undefined */ 0, state_undefined },
3776 { /*187, undefined */ 0, state_undefined },
3777 { /*188, undefined */ 0, state_undefined },
3778 { /*189, undefined */ 0, state_undefined },
3779 { /*190, undefined */ 0, state_undefined },
3780 { /*191, undefined */ 0, state_undefined },
3781 { /*192, undefined */ 0, state_undefined },
3782 { /*193, undefined */ 0, state_undefined },
3783 { /*194, undefined */ 0, state_undefined },
3784 { /*195, undefined */ 0, state_undefined },
3785 { /*196, undefined */ 0, state_undefined },
3786 { /*197, undefined */ 0, state_undefined },
3787 { /*198, undefined */ 0, state_undefined },
3788 { /*199, undefined */ 0, state_undefined },
3789 { /*200, undefined */ 0, state_undefined },
3790 { /*201, undefined */ 0, state_undefined },
3791 { /*202, undefined */ 0, state_undefined },
3792 { /*203, undefined */ 0, state_undefined },
3793 { /*204, undefined */ 0, state_undefined },
3794 { /*205, undefined */ 0, state_undefined },
3795 { /*206, undefined */ 0, state_undefined },
3796 { /*207, undefined */ 0, state_undefined },
3797 { /*208, undefined */ 0, state_undefined },
3798 { /*209, undefined */ 0, state_undefined },
3799 { /*210, undefined */ 0, state_undefined },
3800 { /*211, undefined */ 0, state_undefined },
3801 { /*212, undefined */ 0, state_undefined },
3802 { /*213, undefined */ 0, state_undefined },
3803 { /*214, undefined */ 0, state_undefined },
3804 { /*215, undefined */ 0, state_undefined },
3805 { /*216, undefined */ 0, state_undefined },
3806 { /*217, undefined */ 0, state_undefined },
3807 { /*218, undefined */ 0, state_undefined },
3808 { /*219, undefined */ 0, state_undefined },
3809 { /*220, undefined */ 0, state_undefined },
3810 { /*221, undefined */ 0, state_undefined },
3811 { /*222, undefined */ 0, state_undefined },
3812 { /*223, undefined */ 0, state_undefined },
3813 { /*224, undefined */ 0, state_undefined },
3814 { /*225, undefined */ 0, state_undefined },
3815 { /*226, undefined */ 0, state_undefined },
3816 { /*227, undefined */ 0, state_undefined },
3817 { /*228, undefined */ 0, state_undefined },
3818 { /*229, undefined */ 0, state_undefined },
3819 { /*230, undefined */ 0, state_undefined },
3820 { /*231, undefined */ 0, state_undefined },
3821 { /*232, undefined */ 0, state_undefined },
3822 { /*233, undefined */ 0, state_undefined },
3823 { /*234, undefined */ 0, state_undefined },
3824 { /*235, undefined */ 0, state_undefined },
3825 { /*236, undefined */ 0, state_undefined },
3826 { /*237, undefined */ 0, state_undefined },
3827 { /*238, undefined */ 0, state_undefined },
3828 { /*239, undefined */ 0, state_undefined },
3829 { /*240, undefined */ 0, state_undefined },
3830 { /*241, undefined */ 0, state_undefined },
3831 { /*242, undefined */ 0, state_undefined },
3832 { /*243, undefined */ 0, state_undefined },
3833 { /*244, undefined */ 0, state_undefined },
3834 { /*245, undefined */ 0, state_undefined },
3835 { /*246, undefined */ 0, state_undefined },
3836 { /*247, undefined */ 0, state_undefined },
3837 { /*248, undefined */ 0, state_undefined },
3838 { /*249, undefined */ 0, state_undefined },
3839 { /*250, undefined */ 0, state_undefined },
3840 { /*251, undefined */ 0, state_undefined },
3841 { /*252, undefined */ 0, state_undefined },
3842 { /*253, undefined */ 0, state_undefined },
3843 { /*254, undefined */ 0, state_undefined },
3844 { /*255, undefined */ 0, state_undefined },
3846 { /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), transform_world },
3847 { /*257, WINED3DTS_WORLDMATRIX(1) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)), transform_worldex },
3848 { /*258, WINED3DTS_WORLDMATRIX(2) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)), transform_worldex },
3849 { /*259, WINED3DTS_WORLDMATRIX(3) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)), transform_worldex },
3850 { /*260, WINED3DTS_WORLDMATRIX(4) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(4)), transform_worldex },
3851 { /*261, WINED3DTS_WORLDMATRIX(5) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(5)), transform_worldex },
3852 { /*262, WINED3DTS_WORLDMATRIX(6) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(6)), transform_worldex },
3853 { /*263, WINED3DTS_WORLDMATRIX(7) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(7)), transform_worldex },
3854 { /*264, WINED3DTS_WORLDMATRIX(8) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(8)), transform_worldex },
3855 { /*265, WINED3DTS_WORLDMATRIX(9) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(9)), transform_worldex },
3856 { /*266, WINED3DTS_WORLDMATRIX(10) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(10)), transform_worldex },
3857 { /*267, WINED3DTS_WORLDMATRIX(11) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(11)), transform_worldex },
3858 { /*268, WINED3DTS_WORLDMATRIX(12) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(12)), transform_worldex },
3859 { /*269, WINED3DTS_WORLDMATRIX(13) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(13)), transform_worldex },
3860 { /*270, WINED3DTS_WORLDMATRIX(14) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(14)), transform_worldex },
3861 { /*271, WINED3DTS_WORLDMATRIX(15) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(15)), transform_worldex },
3862 { /*272, WINED3DTS_WORLDMATRIX(16) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(16)), transform_worldex },
3863 { /*273, WINED3DTS_WORLDMATRIX(17) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(17)), transform_worldex },
3864 { /*274, WINED3DTS_WORLDMATRIX(18) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(18)), transform_worldex },
3865 { /*275, WINED3DTS_WORLDMATRIX(19) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(19)), transform_worldex },
3866 { /*276, WINED3DTS_WORLDMATRIX(20) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(20)), transform_worldex },
3867 { /*277, WINED3DTS_WORLDMATRIX(21) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(21)), transform_worldex },
3868 { /*278, WINED3DTS_WORLDMATRIX(22) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(22)), transform_worldex },
3869 { /*279, WINED3DTS_WORLDMATRIX(23) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(23)), transform_worldex },
3870 { /*280, WINED3DTS_WORLDMATRIX(24) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(24)), transform_worldex },
3871 { /*281, WINED3DTS_WORLDMATRIX(25) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(25)), transform_worldex },
3872 { /*282, WINED3DTS_WORLDMATRIX(26) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(26)), transform_worldex },
3873 { /*283, WINED3DTS_WORLDMATRIX(27) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(27)), transform_worldex },
3874 { /*284, WINED3DTS_WORLDMATRIX(28) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(28)), transform_worldex },
3875 { /*285, WINED3DTS_WORLDMATRIX(29) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(29)), transform_worldex },
3876 { /*286, WINED3DTS_WORLDMATRIX(30) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(30)), transform_worldex },
3877 { /*287, WINED3DTS_WORLDMATRIX(31) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(31)), transform_worldex },
3878 { /*288, WINED3DTS_WORLDMATRIX(32) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(32)), transform_worldex },
3879 { /*289, WINED3DTS_WORLDMATRIX(33) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(33)), transform_worldex },
3880 { /*290, WINED3DTS_WORLDMATRIX(34) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(34)), transform_worldex },
3881 { /*291, WINED3DTS_WORLDMATRIX(35) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(35)), transform_worldex },
3882 { /*292, WINED3DTS_WORLDMATRIX(36) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(36)), transform_worldex },
3883 { /*293, WINED3DTS_WORLDMATRIX(37) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(37)), transform_worldex },
3884 { /*294, WINED3DTS_WORLDMATRIX(38) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(38)), transform_worldex },
3885 { /*295, WINED3DTS_WORLDMATRIX(39) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(39)), transform_worldex },
3886 { /*296, WINED3DTS_WORLDMATRIX(40) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(40)), transform_worldex },
3887 { /*297, WINED3DTS_WORLDMATRIX(41) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(41)), transform_worldex },
3888 { /*298, WINED3DTS_WORLDMATRIX(42) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(42)), transform_worldex },
3889 { /*299, WINED3DTS_WORLDMATRIX(43) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(43)), transform_worldex },
3890 { /*300, WINED3DTS_WORLDMATRIX(44) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(44)), transform_worldex },
3891 { /*301, WINED3DTS_WORLDMATRIX(45) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(45)), transform_worldex },
3892 { /*302, WINED3DTS_WORLDMATRIX(46) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(46)), transform_worldex },
3893 { /*303, WINED3DTS_WORLDMATRIX(47) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(47)), transform_worldex },
3894 { /*304, WINED3DTS_WORLDMATRIX(48) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(48)), transform_worldex },
3895 { /*305, WINED3DTS_WORLDMATRIX(49) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(49)), transform_worldex },
3896 { /*306, WINED3DTS_WORLDMATRIX(50) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(50)), transform_worldex },
3897 { /*307, WINED3DTS_WORLDMATRIX(51) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(51)), transform_worldex },
3898 { /*308, WINED3DTS_WORLDMATRIX(52) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(52)), transform_worldex },
3899 { /*309, WINED3DTS_WORLDMATRIX(53) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(53)), transform_worldex },
3900 { /*310, WINED3DTS_WORLDMATRIX(54) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(54)), transform_worldex },
3901 { /*311, WINED3DTS_WORLDMATRIX(55) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(55)), transform_worldex },
3902 { /*312, WINED3DTS_WORLDMATRIX(56) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(56)), transform_worldex },
3903 { /*313, WINED3DTS_WORLDMATRIX(57) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(57)), transform_worldex },
3904 { /*314, WINED3DTS_WORLDMATRIX(58) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(58)), transform_worldex },
3905 { /*315, WINED3DTS_WORLDMATRIX(59) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(59)), transform_worldex },
3906 { /*316, WINED3DTS_WORLDMATRIX(60) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(60)), transform_worldex },
3907 { /*317, WINED3DTS_WORLDMATRIX(61) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(61)), transform_worldex },
3908 { /*318, WINED3DTS_WORLDMATRIX(62) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(62)), transform_worldex },
3909 { /*319, WINED3DTS_WORLDMATRIX(63) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(63)), transform_worldex },
3910 { /*320, WINED3DTS_WORLDMATRIX(64) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(64)), transform_worldex },
3911 { /*321, WINED3DTS_WORLDMATRIX(65) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(65)), transform_worldex },
3912 { /*322, WINED3DTS_WORLDMATRIX(66) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(66)), transform_worldex },
3913 { /*323, WINED3DTS_WORLDMATRIX(67) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(67)), transform_worldex },
3914 { /*324, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(68)), transform_worldex },
3915 { /*325, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(69)), transform_worldex },
3916 { /*326, WINED3DTS_WORLDMATRIX(70) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(70)), transform_worldex },
3917 { /*327, WINED3DTS_WORLDMATRIX(71) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(71)), transform_worldex },
3918 { /*328, WINED3DTS_WORLDMATRIX(72) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(72)), transform_worldex },
3919 { /*329, WINED3DTS_WORLDMATRIX(73) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(73)), transform_worldex },
3920 { /*330, WINED3DTS_WORLDMATRIX(74) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(74)), transform_worldex },
3921 { /*331, WINED3DTS_WORLDMATRIX(75) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(75)), transform_worldex },
3922 { /*332, WINED3DTS_WORLDMATRIX(76) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(76)), transform_worldex },
3923 { /*333, WINED3DTS_WORLDMATRIX(77) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(77)), transform_worldex },
3924 { /*334, WINED3DTS_WORLDMATRIX(78) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(78)), transform_worldex },
3925 { /*335, WINED3DTS_WORLDMATRIX(79) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(79)), transform_worldex },
3926 { /*336, WINED3DTS_WORLDMATRIX(80) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(80)), transform_worldex },
3927 { /*337, WINED3DTS_WORLDMATRIX(81) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(81)), transform_worldex },
3928 { /*338, WINED3DTS_WORLDMATRIX(82) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(82)), transform_worldex },
3929 { /*339, WINED3DTS_WORLDMATRIX(83) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(83)), transform_worldex },
3930 { /*340, WINED3DTS_WORLDMATRIX(84) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(84)), transform_worldex },
3931 { /*341, WINED3DTS_WORLDMATRIX(85) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(85)), transform_worldex },
3932 { /*341, WINED3DTS_WORLDMATRIX(86) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(86)), transform_worldex },
3933 { /*343, WINED3DTS_WORLDMATRIX(87) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(87)), transform_worldex },
3934 { /*344, WINED3DTS_WORLDMATRIX(88) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(88)), transform_worldex },
3935 { /*345, WINED3DTS_WORLDMATRIX(89) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(89)), transform_worldex },
3936 { /*346, WINED3DTS_WORLDMATRIX(90) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(90)), transform_worldex },
3937 { /*347, WINED3DTS_WORLDMATRIX(91) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(91)), transform_worldex },
3938 { /*348, WINED3DTS_WORLDMATRIX(92) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(92)), transform_worldex },
3939 { /*349, WINED3DTS_WORLDMATRIX(93) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(93)), transform_worldex },
3940 { /*350, WINED3DTS_WORLDMATRIX(94) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(94)), transform_worldex },
3941 { /*351, WINED3DTS_WORLDMATRIX(95) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(95)), transform_worldex },
3942 { /*352, WINED3DTS_WORLDMATRIX(96) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(96)), transform_worldex },
3943 { /*353, WINED3DTS_WORLDMATRIX(97) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(97)), transform_worldex },
3944 { /*354, WINED3DTS_WORLDMATRIX(98) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(98)), transform_worldex },
3945 { /*355, WINED3DTS_WORLDMATRIX(99) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(99)), transform_worldex },
3946 { /*356, WINED3DTS_WORLDMATRIX(100) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), transform_worldex },
3947 { /*357, WINED3DTS_WORLDMATRIX(101) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), transform_worldex },
3948 { /*358, WINED3DTS_WORLDMATRIX(102) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), transform_worldex },
3949 { /*359, WINED3DTS_WORLDMATRIX(103) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), transform_worldex },
3950 { /*360, WINED3DTS_WORLDMATRIX(104) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), transform_worldex },
3951 { /*361, WINED3DTS_WORLDMATRIX(105) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), transform_worldex },
3952 { /*362, WINED3DTS_WORLDMATRIX(106) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), transform_worldex },
3953 { /*363, WINED3DTS_WORLDMATRIX(107) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), transform_worldex },
3954 { /*364, WINED3DTS_WORLDMATRIX(108) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), transform_worldex },
3955 { /*365, WINED3DTS_WORLDMATRIX(109) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), transform_worldex },
3956 { /*366, WINED3DTS_WORLDMATRIX(110) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), transform_worldex },
3957 { /*367, WINED3DTS_WORLDMATRIX(111) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), transform_worldex },
3958 { /*368, WINED3DTS_WORLDMATRIX(112) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), transform_worldex },
3959 { /*369, WINED3DTS_WORLDMATRIX(113) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), transform_worldex },
3960 { /*370, WINED3DTS_WORLDMATRIX(114) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), transform_worldex },
3961 { /*371, WINED3DTS_WORLDMATRIX(115) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), transform_worldex },
3962 { /*372, WINED3DTS_WORLDMATRIX(116) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), transform_worldex },
3963 { /*373, WINED3DTS_WORLDMATRIX(117) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), transform_worldex },
3964 { /*374, WINED3DTS_WORLDMATRIX(118) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), transform_worldex },
3965 { /*375, WINED3DTS_WORLDMATRIX(119) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), transform_worldex },
3966 { /*376, WINED3DTS_WORLDMATRIX(120) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), transform_worldex },
3967 { /*377, WINED3DTS_WORLDMATRIX(121) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), transform_worldex },
3968 { /*378, WINED3DTS_WORLDMATRIX(122) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), transform_worldex },
3969 { /*379, WINED3DTS_WORLDMATRIX(123) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), transform_worldex },
3970 { /*380, WINED3DTS_WORLDMATRIX(124) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), transform_worldex },
3971 { /*381, WINED3DTS_WORLDMATRIX(125) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), transform_worldex },
3972 { /*382, WINED3DTS_WORLDMATRIX(126) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), transform_worldex },
3973 { /*383, WINED3DTS_WORLDMATRIX(127) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), transform_worldex },
3974 { /*384, WINED3DTS_WORLDMATRIX(128) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), transform_worldex },
3975 { /*385, WINED3DTS_WORLDMATRIX(129) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), transform_worldex },
3976 { /*386, WINED3DTS_WORLDMATRIX(130) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), transform_worldex },
3977 { /*387, WINED3DTS_WORLDMATRIX(131) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), transform_worldex },
3978 { /*388, WINED3DTS_WORLDMATRIX(132) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), transform_worldex },
3979 { /*389, WINED3DTS_WORLDMATRIX(133) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), transform_worldex },
3980 { /*390, WINED3DTS_WORLDMATRIX(134) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), transform_worldex },
3981 { /*391, WINED3DTS_WORLDMATRIX(135) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), transform_worldex },
3982 { /*392, WINED3DTS_WORLDMATRIX(136) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), transform_worldex },
3983 { /*393, WINED3DTS_WORLDMATRIX(137) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), transform_worldex },
3984 { /*394, WINED3DTS_WORLDMATRIX(138) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), transform_worldex },
3985 { /*395, WINED3DTS_WORLDMATRIX(139) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), transform_worldex },
3986 { /*396, WINED3DTS_WORLDMATRIX(140) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), transform_worldex },
3987 { /*397, WINED3DTS_WORLDMATRIX(141) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), transform_worldex },
3988 { /*398, WINED3DTS_WORLDMATRIX(142) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), transform_worldex },
3989 { /*399, WINED3DTS_WORLDMATRIX(143) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), transform_worldex },
3990 { /*400, WINED3DTS_WORLDMATRIX(144) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), transform_worldex },
3991 { /*401, WINED3DTS_WORLDMATRIX(145) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), transform_worldex },
3992 { /*402, WINED3DTS_WORLDMATRIX(146) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), transform_worldex },
3993 { /*403, WINED3DTS_WORLDMATRIX(147) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), transform_worldex },
3994 { /*404, WINED3DTS_WORLDMATRIX(148) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), transform_worldex },
3995 { /*405, WINED3DTS_WORLDMATRIX(149) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), transform_worldex },
3996 { /*406, WINED3DTS_WORLDMATRIX(150) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), transform_worldex },
3997 { /*407, WINED3DTS_WORLDMATRIX(151) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), transform_worldex },
3998 { /*408, WINED3DTS_WORLDMATRIX(152) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), transform_worldex },
3999 { /*409, WINED3DTS_WORLDMATRIX(153) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), transform_worldex },
4000 { /*410, WINED3DTS_WORLDMATRIX(154) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), transform_worldex },
4001 { /*411, WINED3DTS_WORLDMATRIX(155) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), transform_worldex },
4002 { /*412, WINED3DTS_WORLDMATRIX(156) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), transform_worldex },
4003 { /*413, WINED3DTS_WORLDMATRIX(157) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), transform_worldex },
4004 { /*414, WINED3DTS_WORLDMATRIX(158) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), transform_worldex },
4005 { /*415, WINED3DTS_WORLDMATRIX(159) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), transform_worldex },
4006 { /*416, WINED3DTS_WORLDMATRIX(160) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), transform_worldex },
4007 { /*417, WINED3DTS_WORLDMATRIX(161) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), transform_worldex },
4008 { /*418, WINED3DTS_WORLDMATRIX(162) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), transform_worldex },
4009 { /*419, WINED3DTS_WORLDMATRIX(163) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), transform_worldex },
4010 { /*420, WINED3DTS_WORLDMATRIX(164) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), transform_worldex },
4011 { /*421, WINED3DTS_WORLDMATRIX(165) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), transform_worldex },
4012 { /*422, WINED3DTS_WORLDMATRIX(166) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), transform_worldex },
4013 { /*423, WINED3DTS_WORLDMATRIX(167) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), transform_worldex },
4014 { /*424, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), transform_worldex },
4015 { /*425, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), transform_worldex },
4016 { /*426, WINED3DTS_WORLDMATRIX(170) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), transform_worldex },
4017 { /*427, WINED3DTS_WORLDMATRIX(171) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), transform_worldex },
4018 { /*428, WINED3DTS_WORLDMATRIX(172) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), transform_worldex },
4019 { /*429, WINED3DTS_WORLDMATRIX(173) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), transform_worldex },
4020 { /*430, WINED3DTS_WORLDMATRIX(174) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), transform_worldex },
4021 { /*431, WINED3DTS_WORLDMATRIX(175) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), transform_worldex },
4022 { /*432, WINED3DTS_WORLDMATRIX(176) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), transform_worldex },
4023 { /*433, WINED3DTS_WORLDMATRIX(177) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), transform_worldex },
4024 { /*434, WINED3DTS_WORLDMATRIX(178) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), transform_worldex },
4025 { /*435, WINED3DTS_WORLDMATRIX(179) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), transform_worldex },
4026 { /*436, WINED3DTS_WORLDMATRIX(180) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), transform_worldex },
4027 { /*437, WINED3DTS_WORLDMATRIX(181) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), transform_worldex },
4028 { /*438, WINED3DTS_WORLDMATRIX(182) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), transform_worldex },
4029 { /*439, WINED3DTS_WORLDMATRIX(183) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), transform_worldex },
4030 { /*440, WINED3DTS_WORLDMATRIX(184) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), transform_worldex },
4031 { /*441, WINED3DTS_WORLDMATRIX(185) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), transform_worldex },
4032 { /*441, WINED3DTS_WORLDMATRIX(186) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), transform_worldex },
4033 { /*443, WINED3DTS_WORLDMATRIX(187) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), transform_worldex },
4034 { /*444, WINED3DTS_WORLDMATRIX(188) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), transform_worldex },
4035 { /*445, WINED3DTS_WORLDMATRIX(189) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), transform_worldex },
4036 { /*446, WINED3DTS_WORLDMATRIX(190) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), transform_worldex },
4037 { /*447, WINED3DTS_WORLDMATRIX(191) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), transform_worldex },
4038 { /*448, WINED3DTS_WORLDMATRIX(192) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), transform_worldex },
4039 { /*449, WINED3DTS_WORLDMATRIX(193) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), transform_worldex },
4040 { /*450, WINED3DTS_WORLDMATRIX(194) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), transform_worldex },
4041 { /*451, WINED3DTS_WORLDMATRIX(195) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), transform_worldex },
4042 { /*452, WINED3DTS_WORLDMATRIX(196) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), transform_worldex },
4043 { /*453, WINED3DTS_WORLDMATRIX(197) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), transform_worldex },
4044 { /*454, WINED3DTS_WORLDMATRIX(198) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), transform_worldex },
4045 { /*455, WINED3DTS_WORLDMATRIX(199) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), transform_worldex },
4046 { /*356, WINED3DTS_WORLDMATRIX(200) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), transform_worldex },
4047 { /*457, WINED3DTS_WORLDMATRIX(201) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), transform_worldex },
4048 { /*458, WINED3DTS_WORLDMATRIX(202) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), transform_worldex },
4049 { /*459, WINED3DTS_WORLDMATRIX(203) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), transform_worldex },
4050 { /*460, WINED3DTS_WORLDMATRIX(204) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), transform_worldex },
4051 { /*461, WINED3DTS_WORLDMATRIX(205) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), transform_worldex },
4052 { /*462, WINED3DTS_WORLDMATRIX(206) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), transform_worldex },
4053 { /*463, WINED3DTS_WORLDMATRIX(207) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), transform_worldex },
4054 { /*464, WINED3DTS_WORLDMATRIX(208) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), transform_worldex },
4055 { /*465, WINED3DTS_WORLDMATRIX(209) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), transform_worldex },
4056 { /*466, WINED3DTS_WORLDMATRIX(210) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), transform_worldex },
4057 { /*467, WINED3DTS_WORLDMATRIX(211) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), transform_worldex },
4058 { /*468, WINED3DTS_WORLDMATRIX(212) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), transform_worldex },
4059 { /*469, WINED3DTS_WORLDMATRIX(213) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), transform_worldex },
4060 { /*470, WINED3DTS_WORLDMATRIX(214) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), transform_worldex },
4061 { /*471, WINED3DTS_WORLDMATRIX(215) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), transform_worldex },
4062 { /*472, WINED3DTS_WORLDMATRIX(216) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), transform_worldex },
4063 { /*473, WINED3DTS_WORLDMATRIX(217) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), transform_worldex },
4064 { /*474, WINED3DTS_WORLDMATRIX(218) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), transform_worldex },
4065 { /*475, WINED3DTS_WORLDMATRIX(219) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), transform_worldex },
4066 { /*476, WINED3DTS_WORLDMATRIX(220) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), transform_worldex },
4067 { /*477, WINED3DTS_WORLDMATRIX(221) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), transform_worldex },
4068 { /*478, WINED3DTS_WORLDMATRIX(222) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), transform_worldex },
4069 { /*479, WINED3DTS_WORLDMATRIX(223) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), transform_worldex },
4070 { /*480, WINED3DTS_WORLDMATRIX(224) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), transform_worldex },
4071 { /*481, WINED3DTS_WORLDMATRIX(225) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), transform_worldex },
4072 { /*482, WINED3DTS_WORLDMATRIX(226) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), transform_worldex },
4073 { /*483, WINED3DTS_WORLDMATRIX(227) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), transform_worldex },
4074 { /*484, WINED3DTS_WORLDMATRIX(228) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), transform_worldex },
4075 { /*485, WINED3DTS_WORLDMATRIX(229) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), transform_worldex },
4076 { /*486, WINED3DTS_WORLDMATRIX(230) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), transform_worldex },
4077 { /*487, WINED3DTS_WORLDMATRIX(231) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), transform_worldex },
4078 { /*488, WINED3DTS_WORLDMATRIX(232) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), transform_worldex },
4079 { /*489, WINED3DTS_WORLDMATRIX(233) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), transform_worldex },
4080 { /*490, WINED3DTS_WORLDMATRIX(234) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), transform_worldex },
4081 { /*491, WINED3DTS_WORLDMATRIX(235) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), transform_worldex },
4082 { /*492, WINED3DTS_WORLDMATRIX(236) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), transform_worldex },
4083 { /*493, WINED3DTS_WORLDMATRIX(237) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), transform_worldex },
4084 { /*494, WINED3DTS_WORLDMATRIX(238) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), transform_worldex },
4085 { /*495, WINED3DTS_WORLDMATRIX(239) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), transform_worldex },
4086 { /*496, WINED3DTS_WORLDMATRIX(240) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), transform_worldex },
4087 { /*497, WINED3DTS_WORLDMATRIX(241) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), transform_worldex },
4088 { /*498, WINED3DTS_WORLDMATRIX(242) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), transform_worldex },
4089 { /*499, WINED3DTS_WORLDMATRIX(243) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), transform_worldex },
4090 { /*500, WINED3DTS_WORLDMATRIX(244) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), transform_worldex },
4091 { /*501, WINED3DTS_WORLDMATRIX(245) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), transform_worldex },
4092 { /*502, WINED3DTS_WORLDMATRIX(246) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), transform_worldex },
4093 { /*503, WINED3DTS_WORLDMATRIX(247) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), transform_worldex },
4094 { /*504, WINED3DTS_WORLDMATRIX(248) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), transform_worldex },
4095 { /*505, WINED3DTS_WORLDMATRIX(249) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), transform_worldex },
4096 { /*506, WINED3DTS_WORLDMATRIX(250) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), transform_worldex },
4097 { /*507, WINED3DTS_WORLDMATRIX(251) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), transform_worldex },
4098 { /*508, WINED3DTS_WORLDMATRIX(252) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), transform_worldex },
4099 { /*509, WINED3DTS_WORLDMATRIX(253) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), transform_worldex },
4100 { /*510, WINED3DTS_WORLDMATRIX(254) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), transform_worldex },
4101 { /*511, WINED3DTS_WORLDMATRIX(255) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), transform_worldex },
4102 /* Various Vertex states follow */
4103 { /* , STATE_STREAMSRC */ STATE_VDECL, vertexdeclaration },
4104 { /* , STATE_INDEXBUFFER */ STATE_INDEXBUFFER, indexbuffer },
4105 { /* , STATE_VDECL */ STATE_VDECL, vertexdeclaration },
4106 { /* , STATE_VSHADER */ STATE_VDECL, vertexdeclaration },
4107 { /* , STATE_VIEWPORT */ STATE_VIEWPORT, viewport },
4108 { /* , STATE_VERTEXSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4109 { /* , STATE_PIXELSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4111 { /* , STATE_ACTIVELIGHT(0) */ STATE_ACTIVELIGHT(0), light },
4112 { /* , STATE_ACTIVELIGHT(1) */ STATE_ACTIVELIGHT(1), light },
4113 { /* , STATE_ACTIVELIGHT(2) */ STATE_ACTIVELIGHT(2), light },
4114 { /* , STATE_ACTIVELIGHT(3) */ STATE_ACTIVELIGHT(3), light },
4115 { /* , STATE_ACTIVELIGHT(4) */ STATE_ACTIVELIGHT(4), light },
4116 { /* , STATE_ACTIVELIGHT(5) */ STATE_ACTIVELIGHT(5), light },
4117 { /* , STATE_ACTIVELIGHT(6) */ STATE_ACTIVELIGHT(6), light },
4118 { /* , STATE_ACTIVELIGHT(7) */ STATE_ACTIVELIGHT(7), light },
4120 { /* Scissor rect */ STATE_SCISSORRECT, scissorrect }