wined3d: Light parameter fixes.
[wine.git] / dlls / wined3d / state.c
blob2b76dff930eb610e9a7a22dbdf14703eacfde725
1 /*
2 * Direct3D state management
4 * Copyright 2002 Lionel Ulmer
5 * Copyright 2002-2005 Jason Edmeades
6 * Copyright 2003-2004 Raphael Junqueira
7 * Copyright 2004 Christian Costa
8 * Copyright 2005 Oliver Stieber
9 * Copyright 2006 Henri Verbeet
10 * Copyright 2006-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
27 #include "config.h"
28 #include <stdio.h>
29 #ifdef HAVE_FLOAT_H
30 # include <float.h>
31 #endif
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]);
46 } else {
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];
63 switch(Value) {
64 case WINED3DFILL_POINT:
65 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
66 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
67 break;
68 case WINED3DFILL_WIREFRAME:
69 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
70 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
71 break;
72 case WINED3DFILL_SOLID:
73 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
74 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
75 break;
76 default:
77 FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
81 static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
82 BOOL transformed;
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)) {
91 return;
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");
101 } else {
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");
112 break;
113 case WINED3DZB_TRUE:
114 glEnable(GL_DEPTH_TEST);
115 checkGLcall("glEnable GL_DEPTH_TEST");
116 break;
117 case WINED3DZB_USEW:
118 glEnable(GL_DEPTH_TEST);
119 checkGLcall("glEnable GL_DEPTH_TEST");
120 FIXME("W buffer is not well handled\n");
121 break;
122 default:
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
132 of back faces */
133 switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
134 case WINED3DCULL_NONE:
135 glDisable(GL_CULL_FACE);
136 checkGLcall("glDisable GL_CULL_FACE");
137 break;
138 case WINED3DCULL_CW:
139 glEnable(GL_CULL_FACE);
140 checkGLcall("glEnable GL_CULL_FACE");
141 if (stateblock->wineD3DDevice->render_offscreen) {
142 glFrontFace(GL_CW);
143 checkGLcall("glFrontFace GL_CW");
144 } else {
145 glFrontFace(GL_CCW);
146 checkGLcall("glFrontFace GL_CCW");
148 glCullFace(GL_BACK);
149 break;
150 case WINED3DCULL_CCW:
151 glEnable(GL_CULL_FACE);
152 checkGLcall("glEnable GL_CULL_FACE");
153 if (stateblock->wineD3DDevice->render_offscreen) {
154 glFrontFace(GL_CCW);
155 checkGLcall("glFrontFace GL_CCW");
156 } else {
157 glFrontFace(GL_CW);
158 checkGLcall("glFrontFace GL_CW");
160 glCullFace(GL_BACK);
161 break;
162 default:
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)");
172 break;
173 case WINED3DSHADE_GOURAUD:
174 glShadeModel(GL_SMOOTH);
175 checkGLcall("glShadeModel(GL_SMOOTH)");
176 break;
177 case WINED3DSHADE_PHONG:
178 FIXME("WINED3DSHADE_PHONG isn't supported\n");
179 break;
180 default:
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]) {
187 glEnable(GL_DITHER);
188 checkGLcall("glEnable GL_DITHER");
189 } else {
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]) {
200 glDepthMask(1);
201 checkGLcall("glDepthMask(1)");
202 } else {
203 glDepthMask(0);
204 checkGLcall("glDepthMask(0)");
208 static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
209 int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
211 if(glParm) {
212 glDepthFunc(glParm);
213 checkGLcall("glDepthFunc");
217 static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
218 float col[4];
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]) {
234 glEnable(GL_BLEND);
235 checkGLcall("glEnable GL_BLEND");
236 } else {
237 glDisable(GL_BLEND);
238 checkGLcall("glDisable GL_BLEND");
239 /* Nothing more to do - get out */
240 return;
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;
258 break;
260 case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
261 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
262 break;
264 case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR; break;
265 case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
266 default:
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;
285 break;
287 case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
288 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
289 break;
291 case WINED3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR; break;
292 case WINED3DBLEND_INVBLENDFACTOR : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
293 default:
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;
309 } else {
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) {
320 float col[4];
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) {
329 int glParm = 0;
330 float ref;
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) {
351 enable_ckey = TRUE;
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");
365 } else {
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
369 * enable call
371 return;
374 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
375 glParm = GL_NOTEQUAL;
376 ref = 0.0;
377 } else {
378 ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
379 glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
381 if(glParm) {
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];
401 } else {
402 disable = 0xffffffff;
403 enable = 0x00;
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 */
421 if (enable) {
422 stateblock->clip_status.ClipUnion = 0;
423 stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
424 } else {
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");
435 return;
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;
444 default:
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");
453 static void
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
460 * some extent.
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
463 * running 1.4 yet!
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);
492 } else {
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()");
501 } else {
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);
511 } else {
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) {
524 unsigned int i;
526 /* Note the texture color applies to all textures whereas
527 * GL_TEXTURE_ENV_COLOR applies to active only
529 float col[4];
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");
541 } else if (i>0) {
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);");
548 } else {
549 GL_EXTCALL(glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, &col[0]));
553 static void
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(...)");
562 else
563 #endif
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(...)");
578 } else {
579 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
583 static void
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;
589 GLint ref = 0;
590 GLuint mask = 0;
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]) ) )
604 func = GL_ALWAYS;
605 if( stateblock->set.renderState[WINED3DRS_CCW_STENCILFUNC] )
606 if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
607 func = GL_ALWAYS;
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);
635 } else {
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(...)");
643 } else {
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;
660 union {
661 DWORD d;
662 float f;
663 } tmpvalue;
665 if (!fogenable) {
666 /* No fog? Disable it, and we're done :-) */
667 glDisable(GL_FOG);
668 checkGLcall("glDisable GL_FOG");
671 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
672 fogstart = tmpvalue.f;
673 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
674 fogend = tmpvalue.f;
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 fogstart = 1.0;
682 fogend = 0.0;
683 context->last_was_foggy_shader = TRUE;
685 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
686 * the system will apply only pixel(=table) fog effects."
688 else if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
689 glHint(GL_FOG_HINT, GL_FASTEST);
690 checkGLcall("glHint(GL_FOG_HINT, GL_FASTEST)");
691 context->last_was_foggy_shader = FALSE;
693 switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
694 /* Processed vertices have their fog factor stored in the specular value. Fall too the none case.
695 * If we are drawing untransformed vertices atm, d3ddevice_set_ortho will update the fog
697 case WINED3DFOG_EXP: {
698 if(!context->last_was_rhw) {
699 glFogi(GL_FOG_MODE, GL_EXP);
700 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
701 if(GL_SUPPORT(EXT_FOG_COORD)) {
702 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
703 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
705 break;
708 case WINED3DFOG_EXP2: {
709 if(!context->last_was_rhw) {
710 glFogi(GL_FOG_MODE, GL_EXP2);
711 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
712 if(GL_SUPPORT(EXT_FOG_COORD)) {
713 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
714 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
716 break;
719 case WINED3DFOG_LINEAR: {
720 if(!context->last_was_rhw) {
721 glFogi(GL_FOG_MODE, GL_LINEAR);
722 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
723 if(GL_SUPPORT(EXT_FOG_COORD)) {
724 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
725 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
727 break;
730 case WINED3DFOG_NONE: {
731 /* Both are none? According to msdn the alpha channel of the specular
732 * color contains a fog factor. Set it in drawStridedSlow.
733 * Same happens with Vertexfog on transformed vertices
735 if(GL_SUPPORT(EXT_FOG_COORD)) {
736 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
737 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)\n");
738 glFogi(GL_FOG_MODE, GL_LINEAR);
739 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
740 fogstart = 0xff;
741 fogend = 0x0;
742 } else {
743 /* Disable GL fog, handle this in software in drawStridedSlow */
744 fogenable = FALSE;
746 break;
748 default: FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
750 } else {
751 glHint(GL_FOG_HINT, GL_NICEST);
752 checkGLcall("glHint(GL_FOG_HINT, GL_NICEST)");
753 context->last_was_foggy_shader = FALSE;
755 switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
756 case WINED3DFOG_EXP:
757 glFogi(GL_FOG_MODE, GL_EXP);
758 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP");
759 if(GL_SUPPORT(EXT_FOG_COORD)) {
760 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
761 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
763 break;
765 case WINED3DFOG_EXP2:
766 glFogi(GL_FOG_MODE, GL_EXP2);
767 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2");
768 if(GL_SUPPORT(EXT_FOG_COORD)) {
769 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
770 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
772 break;
774 case WINED3DFOG_LINEAR:
775 glFogi(GL_FOG_MODE, GL_LINEAR);
776 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR");
777 if(GL_SUPPORT(EXT_FOG_COORD)) {
778 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
779 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT");
781 break;
783 case WINED3DFOG_NONE: /* Won't happen */
784 default:
785 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
789 if(fogenable) {
790 glEnable(GL_FOG);
791 checkGLcall("glEnable GL_FOG");
793 glFogfv(GL_FOG_START, &fogstart);
794 checkGLcall("glFogf(GL_FOG_START, fogstart");
795 TRACE("Fog Start == %f\n", fogstart);
797 glFogfv(GL_FOG_END, &fogend);
798 checkGLcall("glFogf(GL_FOG_END, fogend");
799 TRACE("Fog End == %f\n", fogend);
800 } else {
801 glDisable(GL_FOG);
802 checkGLcall("glDisable GL_FOG");
805 if (GL_SUPPORT(NV_FOG_DISTANCE)) {
806 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
810 static void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
811 float col[4];
812 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
813 /* Set the default alpha blend color */
814 glFogfv(GL_FOG_COLOR, &col[0]);
815 checkGLcall("glFog GL_FOG_COLOR");
818 static void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
819 union {
820 DWORD d;
821 float f;
822 } tmpvalue;
823 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
824 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
825 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
828 /* TODO: Merge with primitive type + init_materials()!! */
829 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
830 IWineD3DDeviceImpl *device = (IWineD3DDeviceImpl *)stateblock->wineD3DDevice;
831 GLenum Parm = 0;
832 WineDirect3DStridedData *diffuse = &device->strided_streams.u.s.diffuse;
833 BOOL isDiffuseSupplied;
835 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
836 * The vertex declaration will call this function if the fixed function pipeline is used.
839 if(isStateDirty(context, STATE_VDECL)) {
840 return;
843 isDiffuseSupplied = diffuse->lpData || diffuse->VBO;
845 if (isDiffuseSupplied && stateblock->renderState[WINED3DRS_COLORVERTEX]) {
846 TRACE("diff %d, amb %d, emis %d, spec %d\n",
847 stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
848 stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
849 stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
850 stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
852 if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
853 if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
854 Parm = GL_AMBIENT_AND_DIFFUSE;
855 } else {
856 Parm = GL_DIFFUSE;
858 } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
859 Parm = GL_AMBIENT;
860 } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
861 Parm = GL_EMISSION;
862 } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
863 Parm = GL_SPECULAR;
867 /* Nothing changed, return. */
868 if (Parm == context->tracking_parm) return;
870 if(!Parm) {
871 glDisable(GL_COLOR_MATERIAL);
872 checkGLcall("glDisable GL_COLOR_MATERIAL");
873 } else {
874 glColorMaterial(GL_FRONT_AND_BACK, Parm);
875 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
876 glEnable(GL_COLOR_MATERIAL);
877 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
880 /* Apparently calls to glMaterialfv are ignored for properties we're
881 * tracking with glColorMaterial, so apply those here. */
882 switch (context->tracking_parm) {
883 case GL_AMBIENT_AND_DIFFUSE:
884 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
885 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
886 checkGLcall("glMaterialfv");
887 break;
889 case GL_DIFFUSE:
890 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
891 checkGLcall("glMaterialfv");
892 break;
894 case GL_AMBIENT:
895 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
896 checkGLcall("glMaterialfv");
897 break;
899 case GL_EMISSION:
900 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
901 checkGLcall("glMaterialfv");
902 break;
904 case GL_SPECULAR:
905 /* Only change material color if specular is enabled, otherwise it is set to black */
906 if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
907 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
908 checkGLcall("glMaterialfv");
909 } else {
910 float black[4] = {0.0f, 0.0f, 0.0f, 0.0f};
911 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
912 checkGLcall("glMaterialfv");
914 break;
917 context->tracking_parm = Parm;
920 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
921 union {
922 DWORD d;
923 WINED3DLINEPATTERN lp;
924 } tmppattern;
925 tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
927 TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
929 if (tmppattern.lp.wRepeatFactor) {
930 glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
931 checkGLcall("glLineStipple(repeat, linepattern)");
932 glEnable(GL_LINE_STIPPLE);
933 checkGLcall("glEnable(GL_LINE_STIPPLE);");
934 } else {
935 glDisable(GL_LINE_STIPPLE);
936 checkGLcall("glDisable(GL_LINE_STIPPLE);");
940 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
941 union {
942 DWORD d;
943 float f;
944 } tmpvalue;
946 if (stateblock->renderState[WINED3DRS_ZBIAS]) {
947 tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
948 TRACE("ZBias value %f\n", tmpvalue.f);
949 glPolygonOffset(0, -tmpvalue.f);
950 checkGLcall("glPolygonOffset(0, -Value)");
951 glEnable(GL_POLYGON_OFFSET_FILL);
952 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
953 glEnable(GL_POLYGON_OFFSET_LINE);
954 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
955 glEnable(GL_POLYGON_OFFSET_POINT);
956 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
957 } else {
958 glDisable(GL_POLYGON_OFFSET_FILL);
959 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
960 glDisable(GL_POLYGON_OFFSET_LINE);
961 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
962 glDisable(GL_POLYGON_OFFSET_POINT);
963 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
968 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
969 if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]) {
970 glEnable(GL_NORMALIZE);
971 checkGLcall("glEnable(GL_NORMALIZE);");
972 } else {
973 glDisable(GL_NORMALIZE);
974 checkGLcall("glDisable(GL_NORMALIZE);");
978 static void state_psize(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
979 union {
980 DWORD d;
981 float f;
982 } tmpvalue;
984 /* FIXME: check that pointSize isn't outside glGetFloatv( GL_POINT_SIZE_MAX_ARB, &maxSize ); or -ve */
985 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE];
986 TRACE("Set point size to %f\n", tmpvalue.f);
987 glPointSize(tmpvalue.f);
988 checkGLcall("glPointSize(...);");
991 static void state_psizemin(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
992 union {
993 DWORD d;
994 float f;
995 } tmpvalue;
997 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
998 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
999 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, tmpvalue.f);
1000 checkGLcall("glPointParameterfARB(...");
1002 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1003 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, tmpvalue.f);
1004 checkGLcall("glPointParameterfEXT(...);");
1005 } else if(tmpvalue.f != 1.0) {
1006 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1010 static void state_psizemax(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1011 union {
1012 DWORD d;
1013 float f;
1014 } tmpvalue;
1016 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1017 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1018 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, tmpvalue.f);
1019 checkGLcall("glPointParameterfARB(...");
1021 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1022 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, tmpvalue.f);
1023 checkGLcall("glPointParameterfEXT(...);");
1024 } else if(tmpvalue.f != 64.0) {
1025 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1029 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1030 /* TODO: Group this with the viewport */
1032 * POINTSCALEENABLE controls how point size value is treated. If set to
1033 * true, the point size is scaled with respect to height of viewport.
1034 * When set to false point size is in pixels.
1036 * http://msdn.microsoft.com/library/en-us/directx9_c/point_sprites.asp
1039 /* Default values */
1040 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1043 * Minimum valid point size for OpenGL is 1.0f. For Direct3D it is 0.0f.
1044 * This means that OpenGL will clamp really small point sizes to 1.0f.
1045 * To correct for this we need to multiply by the scale factor when sizes
1046 * are less than 1.0f. scale_factor = 1.0f / point_size.
1048 GLfloat pointSize = *((float*)&stateblock->renderState[WINED3DRS_POINTSIZE]);
1049 if(pointSize > 0.0f) {
1050 GLfloat scaleFactor;
1052 if(pointSize < 1.0f) {
1053 scaleFactor = pointSize * pointSize;
1054 } else {
1055 scaleFactor = 1.0f;
1058 if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1059 att[0] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_A]) /
1060 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1061 att[1] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_B]) /
1062 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1063 att[2] = *((float*)&stateblock->renderState[WINED3DRS_POINTSCALE_C]) /
1064 (stateblock->viewport.Height * stateblock->viewport.Height * scaleFactor);
1068 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1069 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1070 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...");
1072 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1073 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1074 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...");
1075 } else {
1076 TRACE("POINT_PARAMETERS not supported in this version of opengl\n");
1080 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1081 DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1083 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1084 Value & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1085 Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1086 Value & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1087 Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1088 glColorMask(Value & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1089 Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1090 Value & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1091 Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1092 checkGLcall("glColorMask(...)");
1094 /* depends on WINED3DRS_COLORWRITEENABLE. */
1095 if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
1096 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
1097 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
1098 ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
1099 stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
1100 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
1101 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1105 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1106 if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1107 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1108 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1109 } else {
1110 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1111 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1115 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1116 if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1117 TRACE("Last Pixel Drawing Enabled\n");
1118 } else {
1119 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1123 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1124 unsigned int i;
1125 int val;
1127 /* TODO: NV_POINT_SPRITE */
1128 if (!GL_SUPPORT(ARB_POINT_SPRITE)) {
1129 TRACE("Point sprites not supported\n");
1130 return;
1133 if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1134 val = GL_TRUE;
1135 } else {
1136 val = GL_FALSE;
1139 for (i = 0; i < GL_LIMITS(texture_stages); i++) {
1140 /* Note the WINED3DRS value applies to all textures, but GL has one
1141 * per texture, so apply it now ready to be used!
1143 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1144 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
1145 checkGLcall("glActiveTextureARB");
1146 } else if (i==1) {
1147 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1148 break;
1151 glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, val);
1152 checkGLcall((val?"glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE)":
1153 "glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE)"));
1157 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1159 http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1160 http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/FixedFunction/Textures/texturewrapping.asp
1161 http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1162 Descussion that ways to turn on WRAPing to solve an opengl conversion problem.
1163 http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1165 so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1167 TRACE("Stub\n");
1168 if(stateblock->renderState[WINED3DRS_WRAP0] ||
1169 stateblock->renderState[WINED3DRS_WRAP1] ||
1170 stateblock->renderState[WINED3DRS_WRAP2] ||
1171 stateblock->renderState[WINED3DRS_WRAP3] ||
1172 stateblock->renderState[WINED3DRS_WRAP4] ||
1173 stateblock->renderState[WINED3DRS_WRAP5] ||
1174 stateblock->renderState[WINED3DRS_WRAP6] ||
1175 stateblock->renderState[WINED3DRS_WRAP7] ||
1176 stateblock->renderState[WINED3DRS_WRAP8] ||
1177 stateblock->renderState[WINED3DRS_WRAP9] ||
1178 stateblock->renderState[WINED3DRS_WRAP10] ||
1179 stateblock->renderState[WINED3DRS_WRAP11] ||
1180 stateblock->renderState[WINED3DRS_WRAP12] ||
1181 stateblock->renderState[WINED3DRS_WRAP13] ||
1182 stateblock->renderState[WINED3DRS_WRAP14] ||
1183 stateblock->renderState[WINED3DRS_WRAP15] ) {
1184 ERR("(WINED3DRS_WRAP0) Texture wraping not yet supported\n");
1188 static void state_multisampleaa(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1189 if( GL_SUPPORT(ARB_MULTISAMPLE) ) {
1190 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1191 glEnable(GL_MULTISAMPLE_ARB);
1192 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1193 } else {
1194 glDisable(GL_MULTISAMPLE_ARB);
1195 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1197 } else {
1198 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1199 ERR("Multisample antialiasing not supported by gl\n");
1204 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1205 if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1206 glEnable(GL_SCISSOR_TEST);
1207 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1208 } else {
1209 glDisable(GL_SCISSOR_TEST);
1210 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1214 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1215 union {
1216 DWORD d;
1217 float f;
1218 } tmpvalue;
1220 if(stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] ||
1221 stateblock->renderState[WINED3DRS_DEPTHBIAS]) {
1222 tmpvalue.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1223 glEnable(GL_POLYGON_OFFSET_FILL);
1224 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1225 glPolygonOffset(tmpvalue.f, *((float*)&stateblock->renderState[WINED3DRS_DEPTHBIAS]));
1226 checkGLcall("glPolygonOffset(...)");
1227 } else {
1228 glDisable(GL_POLYGON_OFFSET_FILL);
1229 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1233 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1234 if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1235 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1236 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1237 } else {
1238 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1239 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1243 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1244 TRACE("Stub\n");
1245 if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1246 ERR(" Stippled Alpha not supported yet.\n");
1249 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1250 TRACE("Stub\n");
1251 if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1252 ERR(" Antialias not supported yet.\n");
1255 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1256 TRACE("Stub\n");
1257 if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1258 ERR("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1261 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1262 TRACE("Stub\n");
1263 if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
1264 ERR("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1267 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1268 union {
1269 DWORD d;
1270 float f;
1271 } tmpvalue;
1272 tmpvalue.f = 1.0f;
1274 TRACE("Stub\n");
1275 if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1276 ERR("(WINED3DRS_PATCHSEGMENTS,%d) not yet implemented\n", tmpvalue.d);
1279 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1280 TRACE("Stub\n");
1281 if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
1282 ERR("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1285 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1286 TRACE("Stub\n");
1287 if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
1288 ERR("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1291 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1292 TRACE("Stub\n");
1293 if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1294 FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1298 static void state_srgbwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1299 if(stateblock->renderState[WINED3DRS_SRGBWRITEENABLE])
1300 ERR("Render state WINED3DRS_SRGBWRITEENABLE not yet implemented\n");
1303 static void state_seperateblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1304 TRACE("Stub\n");
1305 if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE])
1306 FIXME("(WINED3DRS_SEPARATEALPHABLENDENABLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]);
1309 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1310 if(stateblock->renderState[WINED3DRS_WRAPU]) {
1311 FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1315 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1316 if(stateblock->renderState[WINED3DRS_WRAPV]) {
1317 FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1321 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1322 if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1323 FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1327 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1328 if(stateblock->renderState[WINED3DRS_ROP2]) {
1329 FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1333 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1334 if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1335 FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1339 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1340 if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1341 FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1345 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1346 if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1347 FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1351 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1352 if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1353 FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1357 static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1358 if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
1359 FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
1363 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1364 if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1365 FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1369 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1370 if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1371 FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1375 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1376 if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1377 FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1381 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1382 if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1383 FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1387 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1388 if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1389 FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1393 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1394 if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1395 FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1399 /* Activates the texture dimension according to the bound D3D texture.
1400 * Does not care for the colorop or correct gl texture unit(when using nvrc)
1401 * Requires the caller to activate the correct unit before
1403 static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock) {
1404 if(stateblock->textures[stage]) {
1405 glDisable(GL_TEXTURE_1D);
1406 checkGLcall("glDisable(GL_TEXTURE_1D)");
1407 switch(stateblock->textureDimensions[stage]) {
1408 case GL_TEXTURE_2D:
1409 glDisable(GL_TEXTURE_3D);
1410 checkGLcall("glDisable(GL_TEXTURE_3D)");
1411 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1412 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1413 glEnable(GL_TEXTURE_2D);
1414 checkGLcall("glEnable(GL_TEXTURE_2D)");
1415 break;
1416 case GL_TEXTURE_3D:
1417 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1418 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1419 glDisable(GL_TEXTURE_2D);
1420 checkGLcall("glDisable(GL_TEXTURE_2D)");
1421 glEnable(GL_TEXTURE_3D);
1422 checkGLcall("glEnable(GL_TEXTURE_3D)");
1423 break;
1424 case GL_TEXTURE_CUBE_MAP_ARB:
1425 glDisable(GL_TEXTURE_2D);
1426 checkGLcall("glDisable(GL_TEXTURE_2D)");
1427 glDisable(GL_TEXTURE_3D);
1428 checkGLcall("glDisable(GL_TEXTURE_3D)");
1429 glEnable(GL_TEXTURE_CUBE_MAP_ARB);
1430 checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
1431 break;
1433 } else {
1434 glDisable(GL_TEXTURE_2D);
1435 checkGLcall("glDisable(GL_TEXTURE_2D)");
1436 glDisable(GL_TEXTURE_3D);
1437 checkGLcall("glDisable(GL_TEXTURE_3D)");
1438 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1439 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1440 glEnable(GL_TEXTURE_1D);
1441 checkGLcall("glEnable(GL_TEXTURE_1D)");
1442 /* Binding textures is done by samplers. A dummy texture will be bound */
1446 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1447 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1448 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1450 TRACE("Setting color op for stage %d\n", stage);
1452 if (stateblock->pixelShader && stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE &&
1453 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1454 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
1455 return;
1458 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
1460 if (mapped_stage != -1) {
1461 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1462 if (mapped_stage >= GL_LIMITS(sampler_stages)) {
1463 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1464 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1465 FIXME("Attempt to enable unsupported stage!\n");
1467 return;
1469 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1470 checkGLcall("glActiveTextureARB");
1471 } else if (stage > 0) {
1472 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1473 return;
1477 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1478 if(stateblock->lowest_disabled_stage > 0) {
1479 glEnable(GL_REGISTER_COMBINERS_NV);
1480 GL_EXTCALL(glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV, stateblock->lowest_disabled_stage));
1481 } else {
1482 glDisable(GL_REGISTER_COMBINERS_NV);
1485 if(stage >= stateblock->lowest_disabled_stage) {
1486 TRACE("Stage disabled\n");
1487 if (mapped_stage != -1) {
1488 /* Disable everything here */
1489 glDisable(GL_TEXTURE_1D);
1490 checkGLcall("glDisable(GL_TEXTURE_1D)");
1491 glDisable(GL_TEXTURE_2D);
1492 checkGLcall("glDisable(GL_TEXTURE_2D)");
1493 glDisable(GL_TEXTURE_3D);
1494 checkGLcall("glDisable(GL_TEXTURE_3D)");
1495 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
1496 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
1498 /* All done */
1499 return;
1502 /* The sampler will also activate the correct texture dimensions, so no need to do it here
1503 * if the sampler for this stage is dirty
1505 if(!isStateDirty(context, STATE_SAMPLER(stage))) {
1506 if (mapped_stage != -1) activate_dimensions(stage, stateblock);
1509 /* Set the texture combiners */
1510 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1511 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1512 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1513 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1514 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1515 stateblock->textureState[stage][WINED3DTSS_COLORARG0],
1516 mapped_stage);
1517 } else {
1518 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
1519 stateblock->textureState[stage][WINED3DTSS_COLOROP],
1520 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
1521 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
1522 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
1526 static void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1527 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1528 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1529 DWORD op, arg1, arg2, arg0;
1531 TRACE("Setting alpha op for stage %d\n", stage);
1532 /* Do not care for enabled / disabled stages, just assign the settigns. colorop disables / enables required stuff */
1533 if (mapped_stage != -1) {
1534 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1535 if (stage >= GL_LIMITS(sampler_stages)) {
1536 if (stateblock->textureState[stage][WINED3DTSS_COLOROP] != WINED3DTOP_DISABLE &&
1537 stateblock->textureState[stage][WINED3DTSS_COLOROP] != 0) {
1538 FIXME("Attempt to enable unsupported stage!\n");
1540 return;
1542 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1543 checkGLcall("glActiveTextureARB");
1544 } else if (stage > 0) {
1545 /* We can't do anything here */
1546 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1547 return;
1551 op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
1552 arg1 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG1];
1553 arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
1554 arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
1556 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 &&
1557 stateblock->textures[0] && stateblock->textureDimensions[0] == GL_TEXTURE_2D) {
1558 IWineD3DSurfaceImpl *surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
1560 if(surf->CKeyFlags & DDSD_CKSRCBLT &&
1561 getFormatDescEntry(surf->resource.format)->alphaMask == 0x00000000) {
1563 /* Color keying needs to pass alpha values from the texture through to have the alpha test work properly.
1564 * On the other hand applications can still use texture combiners apparently. This code takes care that apps
1565 * cannot remove the texture's alpha channel entirely.
1567 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires D3DTOP_MODULATE to work
1568 * on color keyed surfaces.
1570 * What to do with multitexturing? So far no app has been found that uses color keying with multitexturing
1572 if(op == WINED3DTOP_DISABLE) op = WINED3DTOP_SELECTARG1;
1573 if(op == WINED3DTOP_SELECTARG1) arg1 = WINED3DTA_TEXTURE;
1574 else if(op == WINED3DTOP_SELECTARG2) arg2 = WINED3DTA_TEXTURE;
1578 TRACE("Setting alpha op for stage %d\n", stage);
1579 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
1580 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1581 op, arg1, arg2, arg0,
1582 mapped_stage);
1583 } else {
1584 set_tex_op((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
1585 op, arg1, arg2, arg0);
1589 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1590 DWORD texUnit = state - STATE_TRANSFORM(WINED3DTS_TEXTURE0);
1592 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1593 if(texUnit >= GL_LIMITS(sampler_stages)) {
1594 return;
1596 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + stateblock->wineD3DDevice->texUnitMap[texUnit]));
1597 checkGLcall("glActiveTextureARB");
1598 } else if (texUnit > 0) {
1599 /* We can't do anything here */
1600 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1601 return;
1604 set_texture_matrix((float *)&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
1605 stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS],
1606 (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU);
1610 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd);
1612 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1613 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1614 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
1616 if (mapped_stage == -1) {
1617 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
1618 return;
1621 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1622 if(stage >= GL_LIMITS(sampler_stages)) {
1623 return;
1625 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1626 checkGLcall("glActiveTextureARB");
1627 } else if (stage > 0) {
1628 /* We can't do anything here */
1629 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1630 return;
1633 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
1635 * FIXME: From MSDN: The WINED3DTSS_TCI_* flags are mutually exclusive. If you include
1636 * one flag, you can still specify an index value, which the system uses to
1637 * determine the texture wrapping mode.
1638 * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
1639 * means use the vertex position (camera-space) as the input texture coordinates
1640 * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
1641 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
1642 * to the TEXCOORDINDEX value
1646 * Be careful the value of the mask 0xF0000 come from d3d8types.h infos
1648 switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) {
1649 case WINED3DTSS_TCI_PASSTHRU:
1650 /*Use the specified texture coordinates contained within the vertex format. This value resolves to zero.*/
1651 glDisable(GL_TEXTURE_GEN_S);
1652 glDisable(GL_TEXTURE_GEN_T);
1653 glDisable(GL_TEXTURE_GEN_R);
1654 glDisable(GL_TEXTURE_GEN_Q);
1655 checkGLcall("glDisable(GL_TEXTURE_GEN_S,T,R,Q)");
1656 break;
1658 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
1659 /* CameraSpacePosition means use the vertex position, transformed to camera space,
1660 * as the input texture coordinates for this stage's texture transformation. This
1661 * equates roughly to EYE_LINEAR
1664 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1665 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1666 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1667 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1668 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane\n");
1670 glMatrixMode(GL_MODELVIEW);
1671 glPushMatrix();
1672 glLoadIdentity();
1673 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1674 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1675 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1676 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1677 glPopMatrix();
1679 TRACE("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set GL_TEXTURE_GEN_x and GL_x, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR\n");
1680 glEnable(GL_TEXTURE_GEN_S);
1681 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1682 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1683 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1684 glEnable(GL_TEXTURE_GEN_T);
1685 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1686 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1687 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1688 glEnable(GL_TEXTURE_GEN_R);
1689 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1690 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
1691 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)");
1693 break;
1695 case WINED3DTSS_TCI_CAMERASPACENORMAL:
1697 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1698 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1699 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1700 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1701 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1702 TRACE("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane\n");
1704 glMatrixMode(GL_MODELVIEW);
1705 glPushMatrix();
1706 glLoadIdentity();
1707 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1708 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1709 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1710 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1711 glPopMatrix();
1713 glEnable(GL_TEXTURE_GEN_S);
1714 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1715 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1716 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1717 glEnable(GL_TEXTURE_GEN_T);
1718 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1719 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1720 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1721 glEnable(GL_TEXTURE_GEN_R);
1722 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1723 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
1724 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV)");
1727 break;
1729 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
1731 if (GL_SUPPORT(NV_TEXGEN_REFLECTION)) {
1732 float s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
1733 float t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
1734 float r_plane[] = { 0.0, 0.0, 1.0, 0.0 };
1735 float q_plane[] = { 0.0, 0.0, 0.0, 1.0 };
1736 TRACE("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane\n");
1738 glMatrixMode(GL_MODELVIEW);
1739 glPushMatrix();
1740 glLoadIdentity();
1741 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
1742 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
1743 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
1744 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
1745 glPopMatrix();
1747 glEnable(GL_TEXTURE_GEN_S);
1748 checkGLcall("glEnable(GL_TEXTURE_GEN_S);");
1749 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1750 checkGLcall("glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1751 glEnable(GL_TEXTURE_GEN_T);
1752 checkGLcall("glEnable(GL_TEXTURE_GEN_T);");
1753 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1754 checkGLcall("glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1755 glEnable(GL_TEXTURE_GEN_R);
1756 checkGLcall("glEnable(GL_TEXTURE_GEN_R);");
1757 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
1758 checkGLcall("glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV)");
1761 break;
1763 /* Unhandled types: */
1764 default:
1765 /* Todo: */
1766 /* ? disable GL_TEXTURE_GEN_n ? */
1767 glDisable(GL_TEXTURE_GEN_S);
1768 glDisable(GL_TEXTURE_GEN_T);
1769 glDisable(GL_TEXTURE_GEN_R);
1770 glDisable(GL_TEXTURE_GEN_Q);
1771 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %x\n", stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
1772 break;
1775 /* Update the texture matrix */
1776 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
1777 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage), stateblock, context);
1780 if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
1781 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
1782 * source. Call loadVertexData directly because there is no need to reparse the vertex declaration
1783 * and do all the things linked to it
1784 * TODO: Tidy that up to reload only the arrays of the changed unit
1786 loadVertexData(stateblock, &stateblock->wineD3DDevice->strided_streams);
1790 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1791 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1792 union {
1793 DWORD d;
1794 float f;
1795 } tmpvalue;
1797 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLSCALE];
1798 if(tmpvalue.f != 0.0) {
1799 ERR("WINED3DTSS_BUMPENVLSCALE not supported yet\n");
1803 static void tex_bumpenvloffset(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1804 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1805 union {
1806 DWORD d;
1807 float f;
1808 } tmpvalue;
1810 tmpvalue.d = stateblock->textureState[stage][WINED3DTSS_BUMPENVLOFFSET];
1811 if(tmpvalue.f != 0.0) {
1812 ERR("WINED3DTSS_BUMPENVLOFFSET not supported yet\n");
1816 static void tex_resultarg(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1817 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1819 if(stage >= GL_LIMITS(texture_stages)) {
1820 return;
1823 if(stateblock->textureState[stage][WINED3DTSS_RESULTARG] != WINED3DTA_CURRENT) {
1824 ERR("WINED3DTSS_RESULTARG not supported yet\n");
1828 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1829 DWORD sampler = state - STATE_SAMPLER(0);
1830 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
1831 union {
1832 float f;
1833 DWORD d;
1834 } tmpvalue;
1836 TRACE("Sampler: %d\n", sampler);
1837 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
1838 * only has to bind textures and set the per texture states
1841 if (mapped_stage == -1) {
1842 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
1843 return;
1846 if (GL_SUPPORT(ARB_MULTITEXTURE)) {
1847 if(sampler >= GL_LIMITS(sampler_stages)) {
1848 return;
1850 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
1851 checkGLcall("glActiveTextureARB");
1852 } else if (sampler > 0) {
1853 /* We can't do anything here */
1854 WARN("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
1855 return;
1858 if(stateblock->textures[sampler]) {
1859 BOOL texIsPow2 = FALSE;
1861 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
1862 * IWineD3DBaseTexture::ApplyStateChanges multiplies the set matrix with a fixup matrix. Before the
1863 * scaling is reapplied or removed, the texture matrix has to be reapplied
1865 if(!GL_SUPPORT(ARB_TEXTURE_NON_POWER_OF_TWO) && sampler < MAX_TEXTURES) {
1866 if(stateblock->textureDimensions[sampler] == GL_TEXTURE_2D) {
1867 if(((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorX != 1.0 ||
1868 ((IWineD3DTextureImpl *) stateblock->textures[sampler])->pow2scalingFactorY != 1.0 ) {
1869 texIsPow2 = TRUE;
1871 } else if(stateblock->textureDimensions[sampler] == GL_TEXTURE_CUBE_MAP_ARB) {
1872 if(((IWineD3DCubeTextureImpl *) stateblock->textures[sampler])->pow2scalingFactor != 1.0) {
1873 texIsPow2 = TRUE;
1877 if(texIsPow2 || context->lastWasPow2Texture[sampler]) {
1878 transform_texture(STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stateblock->wineD3DDevice->texUnitMap[sampler]), stateblock, context);
1879 context->lastWasPow2Texture[sampler] = texIsPow2;
1883 IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) stateblock->textures[sampler]);
1884 IWineD3DBaseTexture_ApplyStateChanges(stateblock->textures[sampler], stateblock->textureState[sampler], stateblock->samplerState[sampler]);
1886 if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
1887 tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
1888 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
1889 GL_TEXTURE_LOD_BIAS_EXT,
1890 tmpvalue.f);
1891 checkGLcall("glTexEnvi GL_TEXTURE_LOD_BIAS_EXT ...");
1894 if (stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader &&
1895 ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function) {
1896 /* Using a pixel shader? Verify the sampler types */
1898 /* Make sure that the texture dimensions are enabled. I don't have to disable the other
1899 * dimensions because the shader knows from which texture type to sample from. For the sake of
1900 * debugging all dimensions could be enabled and a texture with some ugly pink bound to the unused
1901 * dimensions. This should make wrong sampling sources visible :-)
1903 glEnable(stateblock->textureDimensions[sampler]);
1904 checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
1905 } else if(sampler < stateblock->lowest_disabled_stage) {
1906 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
1907 activate_dimensions(sampler, stateblock);
1910 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
1911 /* If color keying is enabled update the alpha test, it depends on the existence
1912 * of a color key in stage 0
1914 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
1917 } else if(sampler < GL_LIMITS(texture_stages)) {
1918 if(sampler < stateblock->lowest_disabled_stage) {
1919 /* TODO: What should I do with pixel shaders here ??? */
1920 if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
1921 activate_dimensions(sampler, stateblock);
1923 } /* Otherwise tex_colorop disables the stage */
1924 glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
1925 checkGLcall("glBindTexture(GL_TEXTURE_1D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
1929 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1930 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
1932 /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
1933 * has an update pending
1935 if(isStateDirty(context, STATE_VDECL) ||
1936 isStateDirty(context, STATE_PIXELSHADER)) {
1937 return;
1940 device->shader_backend->shader_load_constants((IWineD3DDevice *) device,
1941 stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function,
1942 stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function);
1945 static void pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1946 BOOL use_ps = stateblock->pixelShader && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function != NULL;
1947 BOOL use_vs = stateblock->vertexShader && ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL;
1948 int i;
1950 if (use_ps) {
1951 if(!context->last_was_pshader) {
1952 /* Former draw without a pixel shader, some samplers
1953 * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
1954 * make sure to enable them
1956 for(i=0; i < MAX_SAMPLERS; i++) {
1957 if(!isStateDirty(context, STATE_SAMPLER(i))) {
1958 sampler(STATE_SAMPLER(i), stateblock, context);
1961 } else {
1962 /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
1963 * if a different texture was bound. I don't have to do anything.
1967 /* Compile and bind the shader */
1968 IWineD3DPixelShader_CompileShader(stateblock->pixelShader);
1969 } else {
1970 /* Disabled the pixel shader - color ops weren't applied
1971 * while it was enabled, so re-apply them.
1973 for(i=0; i < MAX_TEXTURES; i++) {
1974 if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
1975 tex_colorop(STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
1980 if(!isStateDirty(context, StateTable[STATE_VSHADER].representative)) {
1981 stateblock->wineD3DDevice->shader_backend->shader_select((IWineD3DDevice *)stateblock->wineD3DDevice, use_ps, use_vs);
1983 if(!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vs || use_ps)) {
1984 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
1988 context->last_was_pshader = use_ps;
1991 static void tex_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
1992 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
1994 if(stateblock->pixelShader && stage != 0 &&
1995 ((IWineD3DPixelShaderImpl *) stateblock->pixelShader)->needsbumpmat == stage) {
1996 /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
1997 * anyway
1999 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
2000 !isStateDirty(context, STATE_PIXELSHADER)) {
2001 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
2006 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2007 /* This function is called by transform_view below if the view matrix was changed too
2009 * Deliberately no check if the vertex declaration is dirty because the vdecl state
2010 * does not always update the world matrix, only on a switch between transformed
2011 * and untrannsformed draws. It *may* happen that the world matrix is set 2 times during one
2012 * draw, but that should be rather rare and cheaper in total.
2014 glMatrixMode(GL_MODELVIEW);
2015 checkGLcall("glMatrixMode");
2017 if(context->last_was_rhw) {
2018 glLoadIdentity();
2019 checkGLcall("glLoadIdentity()");
2020 } else {
2021 /* In the general case, the view matrix is the identity matrix */
2022 if (stateblock->wineD3DDevice->view_ident) {
2023 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2024 checkGLcall("glLoadMatrixf");
2025 } else {
2026 glLoadMatrixf((float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2027 checkGLcall("glLoadMatrixf");
2028 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
2029 checkGLcall("glMultMatrixf");
2034 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2035 unsigned int k;
2037 /* If we are changing the View matrix, reset the light and clipping planes to the new view
2038 * NOTE: We have to reset the positions even if the light/plane is not currently
2039 * enabled, since the call to enable it will not reset the position.
2040 * NOTE2: Apparently texture transforms do NOT need reapplying
2043 PLIGHTINFOEL *light = NULL;
2045 glMatrixMode(GL_MODELVIEW);
2046 checkGLcall("glMatrixMode(GL_MODELVIEW)");
2047 glLoadMatrixf((float *)(float *) &stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2048 checkGLcall("glLoadMatrixf(...)");
2050 /* Reset lights. TODO: Call light apply func */
2051 for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) {
2052 light = stateblock->activeLights[k];
2053 if(!light) continue;
2054 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
2055 checkGLcall("glLightfv posn");
2056 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
2057 checkGLcall("glLightfv dirn");
2060 /* Reset Clipping Planes if clipping is enabled. TODO: Call clipplane apply func */
2061 for (k = 0; k < GL_LIMITS(clipplanes); k++) {
2062 glClipPlane(GL_CLIP_PLANE0 + k, stateblock->clipplane[k]);
2063 checkGLcall("glClipPlane");
2066 if(context->last_was_rhw) {
2067 glLoadIdentity();
2068 checkGLcall("glLoadIdentity()");
2069 /* No need to update the world matrix, the identity is fine */
2070 return;
2073 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
2074 * No need to do it here if the state is scheduled for update.
2076 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
2077 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2081 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2082 WARN("World matrix 1 - 255 not supported yet\n");
2085 static const GLfloat invymat[16] = {
2086 1.0f, 0.0f, 0.0f, 0.0f,
2087 0.0f, -1.0f, 0.0f, 0.0f,
2088 0.0f, 0.0f, 1.0f, 0.0f,
2089 0.0f, 0.0f, 0.0f, 1.0f};
2091 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2092 glMatrixMode(GL_PROJECTION);
2093 checkGLcall("glMatrixMode(GL_PROJECTION)");
2094 glLoadIdentity();
2095 checkGLcall("glLoadIdentity");
2097 if(context->last_was_rhw) {
2098 double X, Y, height, width, minZ, maxZ;
2100 X = stateblock->viewport.X;
2101 Y = stateblock->viewport.Y;
2102 height = stateblock->viewport.Height;
2103 width = stateblock->viewport.Width;
2104 minZ = stateblock->viewport.MinZ;
2105 maxZ = stateblock->viewport.MaxZ;
2107 if(!stateblock->wineD3DDevice->untransformed) {
2108 /* Transformed vertices are supposed to bypass the whole transform pipeline including
2109 * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
2110 * suppress depth clipping. This can be done because it is an orthogonal projection and
2111 * the Z coordinate does not affect the size of the primitives
2113 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
2114 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
2115 } else {
2116 /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
2117 * trick above because this would mess up transformed and untransformed Z order. Pass the z position
2118 * unmodified to opengl.
2120 * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
2121 * replacement shader.
2123 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
2124 glOrtho(X, X + width, Y + height, Y, 1.0, -1.0);
2126 checkGLcall("glOrtho");
2128 /* Window Coord 0 is the middle of the first pixel, so translate by 3/8 pixels */
2129 glTranslatef(0.375, 0.375, 0);
2130 checkGLcall("glTranslatef(0.375, 0.375, 0)");
2131 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2132 * render everything upside down when rendering offscreen. */
2133 if (stateblock->wineD3DDevice->render_offscreen) {
2134 glMultMatrixf(invymat);
2135 checkGLcall("glMultMatrixf(invymat)");
2137 } else {
2138 /* The rule is that the window coordinate 0 does not correspond to the
2139 beginning of the first pixel, but the center of the first pixel.
2140 As a consequence if you want to correctly draw one line exactly from
2141 the left to the right end of the viewport (with all matrices set to
2142 be identity), the x coords of both ends of the line would be not
2143 -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
2144 instead. */
2145 glTranslatef(0.9 / stateblock->viewport.Width, -0.9 / stateblock->viewport.Height, 0);
2146 checkGLcall("glTranslatef (0.9 / width, -0.9 / height, 0)");
2148 /* D3D texture coordinates are flipped compared to OpenGL ones, so
2149 * render everything upside down when rendering offscreen. */
2150 if (stateblock->wineD3DDevice->render_offscreen) {
2151 glMultMatrixf(invymat);
2152 checkGLcall("glMultMatrixf(invymat)");
2154 glMultMatrixf((float *) &stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
2155 checkGLcall("glLoadMatrixf");
2159 /* This should match any arrays loaded in loadVertexData.
2160 * stateblock impl is required for GL_SUPPORT
2161 * TODO: Only load / unload arrays if we have to.
2163 static inline void unloadVertexData(IWineD3DStateBlockImpl *stateblock) {
2164 int texture_idx;
2166 glDisableClientState(GL_VERTEX_ARRAY);
2167 glDisableClientState(GL_NORMAL_ARRAY);
2168 glDisableClientState(GL_COLOR_ARRAY);
2169 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2170 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2172 for (texture_idx = 0; texture_idx < GL_LIMITS(textures); ++texture_idx) {
2173 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2174 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2178 /* This should match any arrays loaded in loadNumberedArrays
2179 * TODO: Only load / unload arrays if we have to.
2181 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock) {
2182 /* disable any attribs (this is the same for both GLSL and ARB modes) */
2183 GLint maxAttribs;
2184 int i;
2186 /* Leave all the attribs disabled */
2187 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
2188 /* MESA does not support it right not */
2189 if (glGetError() != GL_NO_ERROR)
2190 maxAttribs = 16;
2191 for (i = 0; i < maxAttribs; ++i) {
2192 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2193 checkGLcall("glDisableVertexAttribArrayARB(reg);");
2197 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *strided) {
2198 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2199 int i;
2200 UINT *offset = stateblock->streamOffset;
2202 /* Default to no instancing */
2203 stateblock->wineD3DDevice->instancedDraw = FALSE;
2205 for (i = 0; i < MAX_ATTRIBS; i++) {
2207 if (!strided->u.input[i].lpData && !strided->u.input[i].VBO)
2208 continue;
2210 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
2211 if(stateblock->streamFlags[strided->u.input[i].streamNo] & WINED3DSTREAMSOURCE_INSTANCEDATA) {
2212 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2213 stateblock->wineD3DDevice->instancedDraw = TRUE;
2214 continue;
2217 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, strided->u.input[i].VBO);
2219 if(strided->u.input[i].dwStride) {
2220 if(curVBO != strided->u.input[i].VBO) {
2221 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, strided->u.input[i].VBO));
2222 checkGLcall("glBindBufferARB");
2223 curVBO = strided->u.input[i].VBO;
2225 GL_EXTCALL(glVertexAttribPointerARB(i,
2226 WINED3D_ATR_SIZE(strided->u.input[i].dwType),
2227 WINED3D_ATR_GLTYPE(strided->u.input[i].dwType),
2228 WINED3D_ATR_NORMALIZED(strided->u.input[i].dwType),
2229 strided->u.input[i].dwStride,
2230 strided->u.input[i].lpData + stateblock->loadBaseVertexIndex * strided->u.input[i].dwStride + offset[strided->u.input[i].streamNo]) );
2231 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
2232 } else {
2233 /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
2234 * set up the attribute statically. But we have to figure out the system memory address.
2236 BYTE *ptr = strided->u.input[i].lpData + offset[strided->u.input[i].streamNo];
2237 if(strided->u.input[i].VBO) {
2238 IWineD3DVertexBufferImpl *vb = (IWineD3DVertexBufferImpl *) stateblock->streamSource[strided->u.input[i].streamNo];
2239 ptr += (long) vb->resource.allocatedMemory;
2241 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
2243 switch(strided->u.input[i].dwType) {
2244 case WINED3DDECLTYPE_FLOAT1:
2245 GL_EXTCALL(glVertexAttrib1fvARB(i, (float *) ptr));
2246 break;
2247 case WINED3DDECLTYPE_FLOAT2:
2248 GL_EXTCALL(glVertexAttrib2fvARB(i, (float *) ptr));
2249 break;
2250 case WINED3DDECLTYPE_FLOAT3:
2251 GL_EXTCALL(glVertexAttrib3fvARB(i, (float *) ptr));
2252 break;
2253 case WINED3DDECLTYPE_FLOAT4:
2254 GL_EXTCALL(glVertexAttrib4fvARB(i, (float *) ptr));
2255 break;
2257 case WINED3DDECLTYPE_UBYTE4:
2258 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2259 break;
2260 case WINED3DDECLTYPE_UBYTE4N:
2261 case WINED3DDECLTYPE_D3DCOLOR:
2262 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
2263 break;
2265 case WINED3DDECLTYPE_SHORT2:
2266 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2267 break;
2268 case WINED3DDECLTYPE_SHORT4:
2269 GL_EXTCALL(glVertexAttrib4svARB(i, (GLshort *) ptr));
2270 break;
2272 case WINED3DDECLTYPE_SHORT2N:
2274 GLshort s[4] = {((short *) ptr)[0], ((short *) ptr)[1], 0, 1};
2275 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
2276 break;
2278 case WINED3DDECLTYPE_USHORT2N:
2280 GLushort s[4] = {((unsigned short *) ptr)[0], ((unsigned short *) ptr)[1], 0, 1};
2281 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
2282 break;
2284 case WINED3DDECLTYPE_SHORT4N:
2285 GL_EXTCALL(glVertexAttrib4NsvARB(i, (GLshort *) ptr));
2286 break;
2287 case WINED3DDECLTYPE_USHORT4N:
2288 GL_EXTCALL(glVertexAttrib4NusvARB(i, (GLushort *) ptr));
2289 break;
2291 case WINED3DDECLTYPE_UDEC3:
2292 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
2293 /*glVertexAttrib3usvARB(i, (GLushort *) ptr); Does not exist */
2294 break;
2295 case WINED3DDECLTYPE_DEC3N:
2296 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
2297 /*glVertexAttrib3NusvARB(i, (GLushort *) ptr); Does not exist */
2298 break;
2300 case WINED3DDECLTYPE_FLOAT16_2:
2301 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
2302 * byte float according to the IEEE standard
2304 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
2305 break;
2306 case WINED3DDECLTYPE_FLOAT16_4:
2307 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
2308 break;
2310 case WINED3DDECLTYPE_UNUSED:
2311 default:
2312 ERR("Unexpected declaration in stride 0 attributes\n");
2313 break;
2320 /* Used from 2 different functions, and too big to justify making it inlined */
2321 static void loadVertexData(IWineD3DStateBlockImpl *stateblock, WineDirect3DVertexStridedData *sd) {
2322 unsigned int textureNo = 0;
2323 unsigned int texture_idx = 0;
2324 UINT *offset = stateblock->streamOffset;
2325 GLint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? -1 : 0;
2327 TRACE("Using fast vertex array code\n");
2329 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
2330 stateblock->wineD3DDevice->instancedDraw = FALSE;
2332 /* Blend Data ---------------------------------------------- */
2333 if( (sd->u.s.blendWeights.lpData) || (sd->u.s.blendWeights.VBO) ||
2334 (sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO) ) {
2337 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2339 #if 1
2340 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
2341 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
2342 #endif
2344 TRACE("Blend %d %p %d\n", WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2345 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride, sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2346 /* FIXME("TODO\n");*/
2347 /* Note dwType == float3 or float4 == 2 or 3 */
2349 #if 0
2350 /* with this on, the normals appear to be being modified,
2351 but the vertices aren't being translated as they should be
2352 Maybe the world matrix aren't being setup properly? */
2353 glVertexBlendARB(WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) + 1);
2354 #endif
2357 VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
2358 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType) ,
2359 sd->u.s.blendWeights.dwStride,
2360 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
2362 if(curVBO != sd->u.s.blendWeights.VBO) {
2363 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.blendWeights.VBO));
2364 checkGLcall("glBindBufferARB");
2365 curVBO = sd->u.s.blendWeights.VBO;
2368 GL_EXTCALL(glWeightPointerARB)(
2369 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2370 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2371 sd->u.s.blendWeights.dwStride,
2372 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]);
2374 checkGLcall("glWeightPointerARB");
2376 if((sd->u.s.blendMatrixIndices.lpData) || (sd->u.s.blendMatrixIndices.VBO)){
2377 static BOOL showfixme = TRUE;
2378 if(showfixme){
2379 FIXME("blendMatrixIndices support\n");
2380 showfixme = FALSE;
2384 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2385 /* FIXME("TODO\n");*/
2386 #if 0
2388 GL_EXTCALL(glVertexWeightPointerEXT)(
2389 WINED3D_ATR_SIZE(sd->u.s.blendWeights.dwType),
2390 WINED3D_ATR_GLTYPE(sd->u.s.blendWeights.dwType),
2391 sd->u.s.blendWeights.dwStride,
2392 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride);
2393 checkGLcall("glVertexWeightPointerEXT(numBlends, ...)");
2394 glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2395 checkGLcall("glEnableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2396 #endif
2398 } else {
2399 /* TODO: support blends in drawStridedSlow
2400 * No need to write a FIXME here, this is done after the general vertex decl decoding
2402 WARN("unsupported blending in openGl\n");
2404 } else {
2405 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
2406 #if 0 /* TODO: Vertex blending */
2407 glDisable(GL_VERTEX_BLEND_ARB);
2408 #endif
2409 TRACE("ARB_VERTEX_BLEND\n");
2410 } else if (GL_SUPPORT(EXT_VERTEX_WEIGHTING)) {
2411 TRACE(" EXT_VERTEX_WEIGHTING\n");
2412 glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT);
2413 checkGLcall("glDisableClientState(GL_VERTEX_WEIGHT_ARRAY_EXT)");
2418 #if 0 /* FOG ----------------------------------------------*/
2419 if (sd->u.s.fog.lpData || sd->u.s.fog.VBO) {
2420 /* TODO: fog*/
2421 if (GL_SUPPORT(EXT_FOG_COORD) {
2422 glEnableClientState(GL_FOG_COORDINATE_EXT);
2423 (GL_EXTCALL)(FogCoordPointerEXT)(
2424 WINED3D_ATR_GLTYPE(sd->u.s.fog.dwType),
2425 sd->u.s.fog.dwStride,
2426 sd->u.s.fog.lpData + stateblock->loadBaseVertexIndex * sd->u.s.fog.dwStride);
2427 } else {
2428 /* don't bother falling back to 'slow' as we don't support software FOG yet. */
2429 /* FIXME: fixme once */
2430 TRACE("Hardware support for FOG is not avaiable, FOG disabled.\n");
2432 } else {
2433 if (GL_SUPPRT(EXT_FOR_COORD) {
2434 /* make sure fog is disabled */
2435 glDisableClientState(GL_FOG_COORDINATE_EXT);
2438 #endif
2440 #if 0 /* tangents ----------------------------------------------*/
2441 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO ||
2442 sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2443 /* TODO: tangents*/
2444 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2445 if (sd->u.s.tangent.lpData || sd->u.s.tangent.VBO) {
2446 glEnable(GL_TANGENT_ARRAY_EXT);
2447 (GL_EXTCALL)(TangentPointerEXT)(
2448 WINED3D_ATR_GLTYPE(sd->u.s.tangent.dwType),
2449 sd->u.s.tangent.dwStride,
2450 sd->u.s.tangent.lpData + stateblock->loadBaseVertexIndex * sd->u.s.tangent.dwStride);
2451 } else {
2452 glDisable(GL_TANGENT_ARRAY_EXT);
2454 if (sd->u.s.binormal.lpData || sd->u.s.binormal.VBO) {
2455 glEnable(GL_BINORMAL_ARRAY_EXT);
2456 (GL_EXTCALL)(BinormalPointerEXT)(
2457 WINED3D_ATR_GLTYPE(sd->u.s.binormal.dwType),
2458 sd->u.s.binormal.dwStride,
2459 sd->u.s.binormal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.binormal.dwStride);
2460 } else{
2461 glDisable(GL_BINORMAL_ARRAY_EXT);
2464 } else {
2465 /* don't bother falling back to 'slow' as we don't support software tangents and binormals yet . */
2466 /* FIXME: fixme once */
2467 TRACE("Hardware support for tangents and binormals is not avaiable, tangents and binormals disabled.\n");
2469 } else {
2470 if (GL_SUPPORT(EXT_COORDINATE_FRAME) {
2471 /* make sure fog is disabled */
2472 glDisable(GL_TANGENT_ARRAY_EXT);
2473 glDisable(GL_BINORMAL_ARRAY_EXT);
2476 #endif
2478 /* Point Size ----------------------------------------------*/
2479 if (sd->u.s.pSize.lpData || sd->u.s.pSize.VBO) {
2481 /* no such functionality in the fixed function GL pipeline */
2482 TRACE("Cannot change ptSize here in openGl\n");
2483 /* TODO: Implement this function in using shaders if they are available */
2487 /* Vertex Pointers -----------------------------------------*/
2488 if (sd->u.s.position.lpData != NULL || sd->u.s.position.VBO != 0) {
2489 /* Note dwType == float3 or float4 == 2 or 3 */
2490 VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n",
2491 sd->u.s.position.dwStride,
2492 sd->u.s.position.dwType + 1,
2493 sd->u.s.position.lpData));
2495 if(curVBO != sd->u.s.position.VBO) {
2496 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.position.VBO));
2497 checkGLcall("glBindBufferARB");
2498 curVBO = sd->u.s.position.VBO;
2501 /* min(WINED3D_ATR_SIZE(position),3) to Disable RHW mode as 'w' coord
2502 handling for rhw mode should not impact screen position whereas in GL it does.
2503 This may result in very slightly distored textures in rhw mode, but
2504 a very minimal different. There's always the other option of
2505 fixing the view matrix to prevent w from having any effect
2507 This only applies to user pointer sources, in VBOs the vertices are fixed up
2509 if(sd->u.s.position.VBO == 0) {
2510 glVertexPointer(3 /* min(WINED3D_ATR_SIZE(sd->u.s.position.dwType),3) */,
2511 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2512 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2513 } else {
2514 glVertexPointer(
2515 WINED3D_ATR_SIZE(sd->u.s.position.dwType),
2516 WINED3D_ATR_GLTYPE(sd->u.s.position.dwType),
2517 sd->u.s.position.dwStride, sd->u.s.position.lpData + stateblock->loadBaseVertexIndex * sd->u.s.position.dwStride + offset[sd->u.s.position.streamNo]);
2519 checkGLcall("glVertexPointer(...)");
2520 glEnableClientState(GL_VERTEX_ARRAY);
2521 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
2523 } else {
2524 glDisableClientState(GL_VERTEX_ARRAY);
2525 checkGLcall("glDisableClientState(GL_VERTEX_ARRAY)");
2528 /* Normals -------------------------------------------------*/
2529 if (sd->u.s.normal.lpData || sd->u.s.normal.VBO) {
2530 /* Note dwType == float3 or float4 == 2 or 3 */
2531 VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n",
2532 sd->u.s.normal.dwStride,
2533 sd->u.s.normal.lpData));
2534 if(curVBO != sd->u.s.normal.VBO) {
2535 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.normal.VBO));
2536 checkGLcall("glBindBufferARB");
2537 curVBO = sd->u.s.normal.VBO;
2539 glNormalPointer(
2540 WINED3D_ATR_GLTYPE(sd->u.s.normal.dwType),
2541 sd->u.s.normal.dwStride,
2542 sd->u.s.normal.lpData + stateblock->loadBaseVertexIndex * sd->u.s.normal.dwStride + offset[sd->u.s.normal.streamNo]);
2543 checkGLcall("glNormalPointer(...)");
2544 glEnableClientState(GL_NORMAL_ARRAY);
2545 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
2547 } else {
2548 glDisableClientState(GL_NORMAL_ARRAY);
2549 checkGLcall("glDisableClientState(GL_NORMAL_ARRAY)");
2550 glNormal3f(0, 0, 1);
2551 checkGLcall("glNormal3f(0, 0, 1)");
2554 /* Diffuse Colour --------------------------------------------*/
2555 /* WARNING: Data here MUST be in RGBA format, so cannot */
2556 /* go directly into fast mode from app pgm, because */
2557 /* directx requires data in BGRA format. */
2558 /* currently fixupVertices swizels the format, but this isn't */
2559 /* very practical when using VBOS */
2560 /* NOTE: Unless we write a vertex shader to swizel the colour */
2561 /* , or the user doesn't care and wants the speed advantage */
2563 if (sd->u.s.diffuse.lpData || sd->u.s.diffuse.VBO) {
2564 /* Note dwType == float3 or float4 == 2 or 3 */
2565 VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2566 sd->u.s.diffuse.dwStride,
2567 sd->u.s.diffuse.lpData));
2569 if(curVBO != sd->u.s.diffuse.VBO) {
2570 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.diffuse.VBO));
2571 checkGLcall("glBindBufferARB");
2572 curVBO = sd->u.s.diffuse.VBO;
2574 glColorPointer(4, GL_UNSIGNED_BYTE,
2575 sd->u.s.diffuse.dwStride,
2576 sd->u.s.diffuse.lpData + stateblock->loadBaseVertexIndex * sd->u.s.diffuse.dwStride + offset[sd->u.s.diffuse.streamNo]);
2577 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
2578 glEnableClientState(GL_COLOR_ARRAY);
2579 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
2581 } else {
2582 glDisableClientState(GL_COLOR_ARRAY);
2583 checkGLcall("glDisableClientState(GL_COLOR_ARRAY)");
2584 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2585 checkGLcall("glColor4f(1, 1, 1, 1)");
2588 /* Specular Colour ------------------------------------------*/
2589 if (sd->u.s.specular.lpData || sd->u.s.specular.VBO) {
2590 TRACE("setting specular colour\n");
2591 /* Note dwType == float3 or float4 == 2 or 3 */
2592 VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n",
2593 sd->u.s.specular.dwStride,
2594 sd->u.s.specular.lpData));
2595 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2596 if(curVBO != sd->u.s.specular.VBO) {
2597 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.specular.VBO));
2598 checkGLcall("glBindBufferARB");
2599 curVBO = sd->u.s.specular.VBO;
2601 GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE,
2602 sd->u.s.specular.dwStride,
2603 sd->u.s.specular.lpData + stateblock->loadBaseVertexIndex * sd->u.s.specular.dwStride + offset[sd->u.s.specular.streamNo]);
2604 vcheckGLcall("glSecondaryColorPointerEXT(4, GL_UNSIGNED_BYTE, ...)");
2605 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2606 vcheckGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2607 } else {
2609 /* Missing specular color is not critical, no warnings */
2610 VTRACE(("Specular colour is not supported in this GL implementation\n"));
2613 } else {
2614 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
2616 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
2617 checkGLcall("glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
2618 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
2619 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
2620 } else {
2622 /* Missing specular color is not critical, no warnings */
2623 VTRACE(("Specular colour is not supported in this GL implementation\n"));
2627 /* Texture coords -------------------------------------------*/
2629 for (textureNo = 0, texture_idx = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
2630 /* The code below uses glClientActiveTexture and glMultiTexCoord* which are all part of the GL_ARB_multitexture extension. */
2631 /* Abort if we don't support the extension. */
2632 if (!GL_SUPPORT(ARB_MULTITEXTURE)) {
2633 FIXME("Program using multiple concurrent textures which this opengl implementation doesn't support\n");
2634 continue;
2637 if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) {
2638 /* Select the correct texture stage */
2639 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
2642 if (stateblock->textures[textureNo] != NULL) {
2643 int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
2645 if (coordIdx >= MAX_TEXTURES) {
2646 VTRACE(("tex: %d - Skip tex coords, as being system generated\n", textureNo));
2647 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2648 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2650 } else if (sd->u.s.texCoords[coordIdx].lpData == NULL && sd->u.s.texCoords[coordIdx].VBO == 0) {
2651 VTRACE(("Bound texture but no texture coordinates supplied, so skipping\n"));
2652 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2653 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + texture_idx, 0, 0, 0, 1));
2655 } else {
2656 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
2657 textureNo, texture_idx, coordIdx, sd->u.s.texCoords[coordIdx].lpData);
2658 if(curVBO != sd->u.s.texCoords[coordIdx].VBO) {
2659 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, sd->u.s.texCoords[coordIdx].VBO));
2660 checkGLcall("glBindBufferARB");
2661 curVBO = sd->u.s.texCoords[coordIdx].VBO;
2663 /* The coords to supply depend completely on the fvf / vertex shader */
2664 glTexCoordPointer(
2665 WINED3D_ATR_SIZE(sd->u.s.texCoords[coordIdx].dwType),
2666 WINED3D_ATR_GLTYPE(sd->u.s.texCoords[coordIdx].dwType),
2667 sd->u.s.texCoords[coordIdx].dwStride,
2668 sd->u.s.texCoords[coordIdx].lpData + stateblock->loadBaseVertexIndex * sd->u.s.texCoords[coordIdx].dwStride + offset[sd->u.s.texCoords[coordIdx].streamNo]);
2669 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2671 } else if (!GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2672 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2673 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2675 if (/*!GL_SUPPORT(NV_REGISTER_COMBINERS) || stateblock->textures[textureNo]*/ TRUE) ++texture_idx;
2677 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
2678 for (textureNo = texture_idx; textureNo < GL_LIMITS(textures); ++textureNo) {
2679 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + textureNo));
2680 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
2681 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
2686 inline void drawPrimitiveTraceDataLocations(
2687 WineDirect3DVertexStridedData *dataLocations) {
2689 /* Dump out what parts we have supplied */
2690 TRACE("Strided Data:\n");
2691 TRACE_STRIDED((dataLocations), position);
2692 TRACE_STRIDED((dataLocations), blendWeights);
2693 TRACE_STRIDED((dataLocations), blendMatrixIndices);
2694 TRACE_STRIDED((dataLocations), normal);
2695 TRACE_STRIDED((dataLocations), pSize);
2696 TRACE_STRIDED((dataLocations), diffuse);
2697 TRACE_STRIDED((dataLocations), specular);
2698 TRACE_STRIDED((dataLocations), texCoords[0]);
2699 TRACE_STRIDED((dataLocations), texCoords[1]);
2700 TRACE_STRIDED((dataLocations), texCoords[2]);
2701 TRACE_STRIDED((dataLocations), texCoords[3]);
2702 TRACE_STRIDED((dataLocations), texCoords[4]);
2703 TRACE_STRIDED((dataLocations), texCoords[5]);
2704 TRACE_STRIDED((dataLocations), texCoords[6]);
2705 TRACE_STRIDED((dataLocations), texCoords[7]);
2706 TRACE_STRIDED((dataLocations), position2);
2707 TRACE_STRIDED((dataLocations), normal2);
2708 TRACE_STRIDED((dataLocations), tangent);
2709 TRACE_STRIDED((dataLocations), binormal);
2710 TRACE_STRIDED((dataLocations), tessFactor);
2711 TRACE_STRIDED((dataLocations), fog);
2712 TRACE_STRIDED((dataLocations), depth);
2713 TRACE_STRIDED((dataLocations), sample);
2715 return;
2718 /* Helper for vertexdeclaration() */
2719 static inline void handleStreams(IWineD3DStateBlockImpl *stateblock, BOOL useVertexShaderFunction, WineD3DContext *context) {
2720 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2721 BOOL fixup = FALSE;
2722 WineDirect3DVertexStridedData *dataLocations = &device->strided_streams;
2724 if(device->up_strided) {
2725 /* Note: this is a ddraw fixed-function code path */
2726 TRACE("================ Strided Input ===================\n");
2727 memcpy(dataLocations, device->up_strided, sizeof(*dataLocations));
2729 if(TRACE_ON(d3d)) {
2730 drawPrimitiveTraceDataLocations(dataLocations);
2732 } else if (stateblock->vertexDecl || stateblock->vertexShader) {
2733 /* Note: This is a fixed function or shader codepath.
2734 * This means it must handle both types of strided data.
2735 * Shaders must go through here to zero the strided data, even if they
2736 * don't set any declaration at all
2738 TRACE("================ Vertex Declaration ===================\n");
2739 memset(dataLocations, 0, sizeof(*dataLocations));
2741 if (stateblock->vertexDecl) {
2742 primitiveDeclarationConvertToStridedData((IWineD3DDevice *) device, useVertexShaderFunction,
2743 dataLocations, &fixup);
2745 } else {
2746 /* Note: This codepath is not reachable from d3d9 (see fvf->decl9 conversion)
2747 * It is reachable through d3d8, but only for fixed-function.
2748 * It will not work properly for shaders.
2750 TRACE("================ FVF ===================\n");
2751 memset(dataLocations, 0, sizeof(*dataLocations));
2752 primitiveConvertToStridedData((IWineD3DDevice *) device, dataLocations, &fixup);
2753 if(TRACE_ON(d3d)) {
2754 drawPrimitiveTraceDataLocations(dataLocations);
2758 /* Unload the old arrays before loading the new ones to get old junk out */
2759 if(context->numberedArraysLoaded) {
2760 unloadNumberedArrays(stateblock);
2761 context->numberedArraysLoaded = FALSE;
2763 if(context->namedArraysLoaded) {
2764 unloadVertexData(stateblock);
2765 context->namedArraysLoaded = FALSE;
2768 if(useVertexShaderFunction) {
2769 TRACE("Loading numbered arrays\n");
2770 loadNumberedArrays(stateblock, dataLocations);
2771 device->useDrawStridedSlow = FALSE;
2772 context->numberedArraysLoaded = TRUE;
2773 } else if (fixup ||
2774 (dataLocations->u.s.pSize.lpData == NULL &&
2775 dataLocations->u.s.diffuse.lpData == NULL &&
2776 dataLocations->u.s.specular.lpData == NULL)) {
2777 /* Load the vertex data using named arrays */
2778 TRACE("Loading vertex data\n");
2779 loadVertexData(stateblock, dataLocations);
2780 device->useDrawStridedSlow = FALSE;
2781 context->namedArraysLoaded = TRUE;
2782 } else {
2783 TRACE("Not loading vertex data\n");
2784 device->useDrawStridedSlow = TRUE;
2787 /* Generate some fixme's if unsupported functionality is being used */
2788 #define BUFFER_OR_DATA(_attribute) dataLocations->u.s._attribute.lpData
2789 /* TODO: Either support missing functionality in fixupVertices or by creating a shader to replace the pipeline. */
2790 if (!useVertexShaderFunction &&
2791 stateblock->renderState[WINED3DRS_VERTEXBLEND] &&
2792 (BUFFER_OR_DATA(blendMatrixIndices) || BUFFER_OR_DATA(blendWeights))) {
2793 FIXME("Vertex Blending is not implemented yet %p %p\n",dataLocations->u.s.blendWeights.lpData,dataLocations->u.s.blendWeights.lpData);
2794 /* TODO: Implement it using GL_ARB_vertex_blend or software emulation in drawStridedSlow */
2796 if (!useVertexShaderFunction && (BUFFER_OR_DATA(position2) || BUFFER_OR_DATA(normal2))) {
2797 FIXME("Tweening is only valid with vertex shaders\n");
2799 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tangent) || BUFFER_OR_DATA(binormal))) {
2800 FIXME("Tangent and binormal bump mapping is only valid with vertex shaders\n");
2802 if (!useVertexShaderFunction && (BUFFER_OR_DATA(tessFactor) || BUFFER_OR_DATA(fog) || BUFFER_OR_DATA(depth) || BUFFER_OR_DATA(sample))) {
2803 FIXME("Extended attributes are only valid with vertex shaders\n");
2805 #undef BUFFER_OR_DATA
2808 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2809 BOOL useVertexShaderFunction = FALSE, updateFog = FALSE;
2810 BOOL usePixelShaderFunction = stateblock->wineD3DDevice->ps_selected_mode != SHADER_NONE && stateblock->pixelShader
2811 && ((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.function;
2812 BOOL transformed;
2813 /* Some stuff is in the device until we have per context tracking */
2814 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
2815 BOOL wasrhw = context->last_was_rhw;
2817 /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
2818 * here simply check whether a shader was set, or the user disabled shaders
2820 if (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader &&
2821 ((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->baseShader.function != NULL) {
2822 useVertexShaderFunction = TRUE;
2824 if(((IWineD3DVertexShaderImpl *)stateblock->vertexShader)->usesFog != context->last_was_foggy_shader) {
2825 updateFog = TRUE;
2827 } else if(context->last_was_foggy_shader) {
2828 updateFog = TRUE;
2831 handleStreams(stateblock, useVertexShaderFunction, context);
2833 /* Do I have to use ? TRUE : FALSE ? Or can I rely on 15==15 being equal to TRUE(=1)? */
2834 transformed = ((device->strided_streams.u.s.position.lpData != NULL ||
2835 device->strided_streams.u.s.position.VBO != 0) &&
2836 device->strided_streams.u.s.position_transformed) ? TRUE : FALSE;
2838 if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
2839 updateFog = TRUE;
2842 /* Reapply lighting if it is not scheduled for reapplication already */
2843 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
2844 state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
2847 if (!useVertexShaderFunction && transformed) {
2848 context->last_was_rhw = TRUE;
2849 } else {
2851 /* Untransformed, so relies on the view and projection matrices */
2852 context->last_was_rhw = FALSE;
2853 /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
2854 device->untransformed = TRUE;
2856 /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
2857 * Not needed as long as only hw shaders are supported
2860 /* This sets the shader output position correction constants.
2861 * TODO: Move to the viewport state
2863 if (useVertexShaderFunction) {
2864 device->posFixup[1] = device->render_offscreen ? -1.0 : 1.0;
2868 /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
2869 * off this function will be called again anyway to make sure they're properly set
2871 if(!useVertexShaderFunction) {
2872 /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
2873 * or transformed / untransformed was switched
2875 if(wasrhw != context->last_was_rhw &&
2876 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
2877 !isStateDirty(context, STATE_VIEWPORT)) {
2878 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
2880 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
2881 * mode.
2883 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
2884 * this check will fail and the matrix not applied again. This is OK because a simple
2885 * world matrix change reapplies the matrix - These checks here are only to satisfy the
2886 * needs of the vertex declaration.
2888 * World and view matrix go into the same gl matrix, so only apply them when neither is
2889 * dirty
2891 if(transformed != wasrhw &&
2892 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
2893 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
2894 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
2897 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
2898 state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
2900 } else {
2901 /* We compile the shader here because we need the vertex declaration
2902 * in order to determine if we need to do any swizzling for D3DCOLOR
2903 * registers. If the shader is already compiled this call will do nothing. */
2904 IWineD3DVertexShader_CompileShader(stateblock->vertexShader);
2907 /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
2908 * application
2910 if (!isStateDirty(context, STATE_PIXELSHADER)) {
2911 device->shader_backend->shader_select((IWineD3DDevice *)device, usePixelShaderFunction, useVertexShaderFunction);
2913 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
2914 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
2918 context->last_was_vshader = useVertexShaderFunction;
2920 if(updateFog) {
2921 state_fog(STATE_RENDER(WINED3DRS_FOGENABLE), stateblock, context);
2925 static void viewport(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2926 glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
2927 checkGLcall("glDepthRange");
2928 /* Note: GL requires lower left, DirectX supplies upper left */
2929 /* TODO: replace usage of renderTarget with context management */
2930 glViewport(stateblock->viewport.X,
2931 (((IWineD3DSurfaceImpl *)stateblock->wineD3DDevice->render_targets[0])->currentDesc.Height - (stateblock->viewport.Y + stateblock->viewport.Height)),
2932 stateblock->viewport.Width, stateblock->viewport.Height);
2934 checkGLcall("glViewport");
2936 stateblock->wineD3DDevice->posFixup[2] = 0.9 / stateblock->viewport.Width;
2937 stateblock->wineD3DDevice->posFixup[3] = -0.9 / stateblock->viewport.Height;
2938 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
2939 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
2944 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
2945 UINT Index = state - STATE_ACTIVELIGHT(0);
2946 PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
2948 if(!lightInfo) {
2949 glDisable(GL_LIGHT0 + Index);
2950 checkGLcall("glDisable(GL_LIGHT0 + Index)");
2951 } else {
2952 float quad_att;
2953 float colRGBA[] = {0.0, 0.0, 0.0, 0.0};
2955 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
2956 glMatrixMode(GL_MODELVIEW);
2957 glPushMatrix();
2958 glLoadMatrixf((float *)&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
2960 /* Diffuse: */
2961 colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
2962 colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
2963 colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
2964 colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
2965 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
2966 checkGLcall("glLightfv");
2968 /* Specular */
2969 colRGBA[0] = lightInfo->OriginalParms.Specular.r;
2970 colRGBA[1] = lightInfo->OriginalParms.Specular.g;
2971 colRGBA[2] = lightInfo->OriginalParms.Specular.b;
2972 colRGBA[3] = lightInfo->OriginalParms.Specular.a;
2973 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
2974 checkGLcall("glLightfv");
2976 /* Ambient */
2977 colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
2978 colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
2979 colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
2980 colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
2981 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
2982 checkGLcall("glLightfv");
2984 if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
2985 quad_att = 1.4/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
2986 } else {
2987 quad_att = 0; /* 0 or MAX? (0 seems to be ok) */
2990 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
2991 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
2992 * Attenuation0 to NaN and crashes in the gl lib
2995 switch (lightInfo->OriginalParms.Type) {
2996 case WINED3DLIGHT_POINT:
2997 /* Position */
2998 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
2999 checkGLcall("glLightfv");
3000 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3001 checkGLcall("glLightf");
3002 /* Attenuation - Are these right? guessing... */
3003 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
3004 checkGLcall("glLightf");
3005 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
3006 checkGLcall("glLightf");
3007 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3008 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3009 checkGLcall("glLightf");
3010 /* FIXME: Range */
3011 break;
3013 case WINED3DLIGHT_SPOT:
3014 /* Position */
3015 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
3016 checkGLcall("glLightfv");
3017 /* Direction */
3018 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
3019 checkGLcall("glLightfv");
3020 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
3021 checkGLcall("glLightf");
3022 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3023 checkGLcall("glLightf");
3024 /* Attenuation - Are these right? guessing... */
3025 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
3026 checkGLcall("glLightf");
3027 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
3028 checkGLcall("glLightf");
3029 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
3030 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
3031 checkGLcall("glLightf");
3032 /* FIXME: Range */
3033 break;
3035 case WINED3DLIGHT_DIRECTIONAL:
3036 /* Direction */
3037 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
3038 checkGLcall("glLightfv");
3039 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
3040 checkGLcall("glLightf");
3041 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
3042 checkGLcall("glLightf");
3043 break;
3045 default:
3046 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
3049 /* Restore the modelview matrix */
3050 glPopMatrix();
3052 glEnable(GL_LIGHT0 + Index);
3053 checkGLcall("glEnable(GL_LIGHT0 + Index)");
3056 return;
3059 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3060 IWineD3DSwapChainImpl *swapchain = (IWineD3DSwapChainImpl *) stateblock->wineD3DDevice->swapchains[0];
3061 RECT *pRect = &stateblock->scissorRect;
3062 RECT windowRect;
3063 UINT winHeight;
3065 GetClientRect(swapchain->win_handle, &windowRect);
3066 /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
3067 * Warning2: Even in windowed mode the coords are relative to the window, not the screen
3069 winHeight = windowRect.bottom - windowRect.top;
3070 TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - winHeight,
3071 pRect->right - pRect->left, pRect->bottom - pRect->top);
3072 glScissor(pRect->left, winHeight - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
3073 checkGLcall("glScissor");
3076 static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
3077 if(GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT)) {
3078 if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
3079 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
3080 } else {
3081 IWineD3DIndexBufferImpl *ib = (IWineD3DIndexBufferImpl *) stateblock->pIndexData;
3082 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->vbo));
3087 const struct StateEntry StateTable[] =
3089 /* State name representative, apply function */
3090 { /* 0, Undefined */ 0, state_undefined },
3091 { /* 1, WINED3DRS_TEXTUREHANDLE */ 0 /* Handled in ddraw */, state_undefined },
3092 { /* 2, WINED3DRS_ANTIALIAS */ STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias },
3093 { /* 3, WINED3DRS_TEXTUREADDRESS */ 0 /* Handled in ddraw */, state_undefined },
3094 { /* 4, WINED3DRS_TEXTUREPERSPECTIVE */ STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective },
3095 { /* 5, WINED3DRS_WRAPU */ STATE_RENDER(WINED3DRS_WRAPU), state_wrapu },
3096 { /* 6, WINED3DRS_WRAPV */ STATE_RENDER(WINED3DRS_WRAPV), state_wrapv },
3097 { /* 7, WINED3DRS_ZENABLE */ STATE_RENDER(WINED3DRS_ZENABLE), state_zenable },
3098 { /* 8, WINED3DRS_FILLMODE */ STATE_RENDER(WINED3DRS_FILLMODE), state_fillmode },
3099 { /* 9, WINED3DRS_SHADEMODE */ STATE_RENDER(WINED3DRS_SHADEMODE), state_shademode },
3100 { /* 10, WINED3DRS_LINEPATTERN */ STATE_RENDER(WINED3DRS_LINEPATTERN), state_linepattern },
3101 { /* 11, WINED3DRS_MONOENABLE */ STATE_RENDER(WINED3DRS_MONOENABLE), state_monoenable },
3102 { /* 12, WINED3DRS_ROP2 */ STATE_RENDER(WINED3DRS_ROP2), state_rop2 },
3103 { /* 13, WINED3DRS_PLANEMASK */ STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask },
3104 { /* 14, WINED3DRS_ZWRITEENABLE */ STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable },
3105 { /* 15, WINED3DRS_ALPHATESTENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3106 { /* 16, WINED3DRS_LASTPIXEL */ STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel },
3107 { /* 17, WINED3DRS_TEXTUREMAG */ 0 /* Handled in ddraw */, state_undefined },
3108 { /* 18, WINED3DRS_TEXTUREMIN */ 0 /* Handled in ddraw */, state_undefined },
3109 { /* 19, WINED3DRS_SRCBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3110 { /* 20, WINED3DRS_DESTBLEND */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3111 { /* 21, WINED3DRS_TEXTUREMAPBLEND */ 0 /* Handled in ddraw */, state_undefined },
3112 { /* 22, WINED3DRS_CULLMODE */ STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode },
3113 { /* 23, WINED3DRS_ZFUNC */ STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc },
3114 { /* 24, WINED3DRS_ALPHAREF */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3115 { /* 25, WINED3DRS_ALPHAFUNC */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3116 { /* 26, WINED3DRS_DITHERENABLE */ STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable },
3117 { /* 27, WINED3DRS_ALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3118 { /* 28, WINED3DRS_FOGENABLE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3119 { /* 29, WINED3DRS_SPECULARENABLE */ STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable},
3120 { /* 30, WINED3DRS_ZVISIBLE */ 0 /* Not supported according to the msdn */, state_nogl },
3121 { /* 31, WINED3DRS_SUBPIXEL */ STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel },
3122 { /* 32, WINED3DRS_SUBPIXELX */ STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx },
3123 { /* 33, WINED3DRS_STIPPLEDALPHA */ STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha },
3124 { /* 34, WINED3DRS_FOGCOLOR */ STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor },
3125 { /* 35, WINED3DRS_FOGTABLEMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3126 { /* 36, WINED3DRS_FOGSTART */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3127 { /* 37, WINED3DRS_FOGEND */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3128 { /* 38, WINED3DRS_FOGDENSITY */ STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity },
3129 { /* 39, WINED3DRS_STIPPLEENABLE */ STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable },
3130 { /* 40, WINED3DRS_EDGEANTIALIAS */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3131 { /* 41, WINED3DRS_COLORKEYENABLE */ STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha },
3132 { /* 42, undefined */ 0, state_undefined },
3133 { /* 43, WINED3DRS_BORDERCOLOR */ STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor },
3134 { /* 44, WINED3DRS_TEXTUREADDRESSU */ 0, /* Handled in ddraw */ state_undefined },
3135 { /* 45, WINED3DRS_TEXTUREADDRESSV */ 0, /* Handled in ddraw */ state_undefined },
3136 { /* 46, WINED3DRS_MIPMAPLODBIAS */ STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias },
3137 { /* 47, WINED3DRS_ZBIAS */ STATE_RENDER(WINED3DRS_ZBIAS), state_zbias },
3138 { /* 48, WINED3DRS_RANGEFOGENABLE */ 0, state_nogl },
3139 { /* 49, WINED3DRS_ANISOTROPY */ STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy },
3140 { /* 50, WINED3DRS_FLUSHBATCH */ STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch },
3141 { /* 51, WINED3DRS_TRANSLUCENTSORTINDEPENDENT */ STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi },
3142 { /* 52, WINED3DRS_STENCILENABLE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3143 { /* 53, WINED3DRS_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3144 { /* 54, WINED3DRS_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3145 { /* 55, WINED3DRS_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3146 { /* 56, WINED3DRS_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3147 { /* 57, WINED3DRS_STENCILREF */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3148 { /* 58, WINED3DRS_STENCILMASK */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3149 { /* 59, WINED3DRS_STENCILWRITEMASK */ STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite },
3150 { /* 60, WINED3DRS_TEXTUREFACTOR */ STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor },
3151 { /* 61, Undefined */ 0, state_undefined },
3152 { /* 62, Undefined */ 0, state_undefined },
3153 { /* 63, Undefined */ 0, state_undefined },
3154 { /* 64, WINED3DRS_STIPPLEPATTERN00 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3155 { /* 65, WINED3DRS_STIPPLEPATTERN01 */ 0 /* Obsolete, should he handled by ddraw */, state_undefined },
3156 { /* 66, WINED3DRS_STIPPLEPATTERN02 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3157 { /* 67, WINED3DRS_STIPPLEPATTERN03 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3158 { /* 68, WINED3DRS_STIPPLEPATTERN04 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3159 { /* 69, WINED3DRS_STIPPLEPATTERN05 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3160 { /* 70, WINED3DRS_STIPPLEPATTERN06 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3161 { /* 71, WINED3DRS_STIPPLEPATTERN07 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3162 { /* 72, WINED3DRS_STIPPLEPATTERN08 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3163 { /* 73, WINED3DRS_STIPPLEPATTERN09 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3164 { /* 74, WINED3DRS_STIPPLEPATTERN10 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3165 { /* 75, WINED3DRS_STIPPLEPATTERN11 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3166 { /* 76, WINED3DRS_STIPPLEPATTERN12 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3167 { /* 77, WINED3DRS_STIPPLEPATTERN13 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3168 { /* 78, WINED3DRS_STIPPLEPATTERN14 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3169 { /* 79, WINED3DRS_STIPPLEPATTERN15 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3170 { /* 80, WINED3DRS_STIPPLEPATTERN16 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3171 { /* 81, WINED3DRS_STIPPLEPATTERN17 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3172 { /* 82, WINED3DRS_STIPPLEPATTERN18 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3173 { /* 83, WINED3DRS_STIPPLEPATTERN19 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3174 { /* 84, WINED3DRS_STIPPLEPATTERN20 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3175 { /* 85, WINED3DRS_STIPPLEPATTERN21 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3176 { /* 86, WINED3DRS_STIPPLEPATTERN22 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3177 { /* 87, WINED3DRS_STIPPLEPATTERN23 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3178 { /* 88, WINED3DRS_STIPPLEPATTERN24 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3179 { /* 89, WINED3DRS_STIPPLEPATTERN25 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3180 { /* 90, WINED3DRS_STIPPLEPATTERN26 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3181 { /* 91, WINED3DRS_STIPPLEPATTERN27 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3182 { /* 92, WINED3DRS_STIPPLEPATTERN28 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3183 { /* 93, WINED3DRS_STIPPLEPATTERN29 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3184 { /* 94, WINED3DRS_STIPPLEPATTERN30 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3185 { /* 95, WINED3DRS_STIPPLEPATTERN31 */ 0 /* Obsolete, should be handled by ddraw */, state_undefined },
3186 { /* 96, Undefined */ 0, state_undefined },
3187 { /* 97, Undefined */ 0, state_undefined },
3188 { /* 98, Undefined */ 0, state_undefined },
3189 { /* 99, Undefined */ 0, state_undefined },
3190 { /*100, Undefined */ 0, state_undefined },
3191 { /*101, Undefined */ 0, state_undefined },
3192 { /*102, Undefined */ 0, state_undefined },
3193 { /*103, Undefined */ 0, state_undefined },
3194 { /*104, Undefined */ 0, state_undefined },
3195 { /*105, Undefined */ 0, state_undefined },
3196 { /*106, Undefined */ 0, state_undefined },
3197 { /*107, Undefined */ 0, state_undefined },
3198 { /*108, Undefined */ 0, state_undefined },
3199 { /*109, Undefined */ 0, state_undefined },
3200 { /*110, Undefined */ 0, state_undefined },
3201 { /*111, Undefined */ 0, state_undefined },
3202 { /*112, Undefined */ 0, state_undefined },
3203 { /*113, Undefined */ 0, state_undefined },
3204 { /*114, Undefined */ 0, state_undefined },
3205 { /*115, Undefined */ 0, state_undefined },
3206 { /*116, Undefined */ 0, state_undefined },
3207 { /*117, Undefined */ 0, state_undefined },
3208 { /*118, Undefined */ 0, state_undefined },
3209 { /*119, Undefined */ 0, state_undefined },
3210 { /*120, Undefined */ 0, state_undefined },
3211 { /*121, Undefined */ 0, state_undefined },
3212 { /*122, Undefined */ 0, state_undefined },
3213 { /*123, Undefined */ 0, state_undefined },
3214 { /*124, Undefined */ 0, state_undefined },
3215 { /*125, Undefined */ 0, state_undefined },
3216 { /*126, Undefined */ 0, state_undefined },
3217 { /*127, Undefined */ 0, state_undefined },
3218 /* Big hole ends */
3219 { /*128, WINED3DRS_WRAP0 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3220 { /*129, WINED3DRS_WRAP1 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3221 { /*130, WINED3DRS_WRAP2 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3222 { /*131, WINED3DRS_WRAP3 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3223 { /*132, WINED3DRS_WRAP4 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3224 { /*133, WINED3DRS_WRAP5 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3225 { /*134, WINED3DRS_WRAP6 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3226 { /*135, WINED3DRS_WRAP7 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3227 { /*136, WINED3DRS_CLIPPING */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3228 { /*137, WINED3DRS_LIGHTING */ STATE_RENDER(WINED3DRS_LIGHTING), state_lighting },
3229 { /*138, WINED3DRS_EXTENTS */ STATE_RENDER(WINED3DRS_EXTENTS), state_extents },
3230 { /*139, WINED3DRS_AMBIENT */ STATE_RENDER(WINED3DRS_AMBIENT), state_ambient },
3231 { /*140, WINED3DRS_FOGVERTEXMODE */ STATE_RENDER(WINED3DRS_FOGENABLE), state_fog },
3232 { /*141, WINED3DRS_COLORVERTEX */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3233 { /*142, WINED3DRS_LOCALVIEWER */ STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer },
3234 { /*143, WINED3DRS_NORMALIZENORMALS */ STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize },
3235 { /*144, WINED3DRS_COLORKEYBLENDENABLE */ STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend },
3236 { /*145, WINED3DRS_DIFFUSEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3237 { /*146, WINED3DRS_SPECULARMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3238 { /*147, WINED3DRS_AMBIENTMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3239 { /*148, WINED3DRS_EMISSIVEMATERIALSOURCE */ STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat },
3240 { /*149, Undefined */ 0, state_undefined },
3241 { /*150, Undefined */ 0, state_undefined },
3242 { /*151, WINED3DRS_VERTEXBLEND */ 0, state_nogl },
3243 { /*152, WINED3DRS_CLIPPLANEENABLE */ STATE_RENDER(WINED3DRS_CLIPPING), state_clipping },
3244 { /*153, WINED3DRS_SOFTWAREVERTEXPROCESSING */ 0, state_nogl },
3245 { /*154, WINED3DRS_POINTSIZE */ STATE_RENDER(WINED3DRS_POINTSIZE), state_psize },
3246 { /*155, WINED3DRS_POINTSIZE_MIN */ STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin },
3247 { /*156, WINED3DRS_POINTSPRITEENABLE */ STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite },
3248 { /*157, WINED3DRS_POINTSCALEENABLE */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3249 { /*158, WINED3DRS_POINTSCALE_A */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3250 { /*159, WINED3DRS_POINTSCALE_B */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3251 { /*160, WINED3DRS_POINTSCALE_C */ STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale },
3252 { /*161, WINED3DRS_MULTISAMPLEANTIALIAS */ STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_multisampleaa },
3253 { /*162, WINED3DRS_MULTISAMPLEMASK */ STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask },
3254 { /*163, WINED3DRS_PATCHEDGESTYLE */ STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), state_patchedgestyle},
3255 { /*164, WINED3DRS_PATCHSEGMENTS */ STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments },
3256 { /*165, WINED3DRS_DEBUGMONITORTOKEN */ STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_nogl },
3257 { /*166, WINED3DRS_POINTSIZE_MAX */ STATE_RENDER(WINED3DRS_POINTSIZE_MAX), state_psizemax },
3258 { /*167, WINED3DRS_INDEXEDVERTEXBLENDENABLE */ 0, state_nogl },
3259 { /*168, WINED3DRS_COLORWRITEENABLE */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3260 { /*169, Undefined */ 0, state_undefined },
3261 { /*170, WINED3DRS_TWEENFACTOR */ 0, state_nogl },
3262 { /*171, WINED3DRS_BLENDOP */ STATE_RENDER(WINED3DRS_BLENDOP), state_blendop },
3263 { /*172, WINED3DRS_POSITIONDEGREE */ STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree},
3264 { /*173, WINED3DRS_NORMALDEGREE */ STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree },
3265 /*172, WINED3DRS_POSITIONORDER */ /* Value assigned to 2 state names */
3266 /*173, WINED3DRS_NORMALORDER */ /* Value assigned to 2 state names */
3267 { /*174, WINED3DRS_SCISSORTESTENABLE */ STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor },
3268 { /*175, WINED3DRS_SLOPESCALEDEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3269 { /*176, WINED3DRS_ANTIALIASEDLINEENABLE */ STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend },
3270 { /*177, undefined */ 0, state_undefined },
3271 { /*178, WINED3DRS_MINTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3272 { /*179, WINED3DRS_MAXTESSELLATIONLEVEL */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3273 { /*180, WINED3DRS_ADAPTIVETESS_X */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3274 { /*181, WINED3DRS_ADAPTIVETESS_Y */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3275 { /*182, WINED3DRS_ADAPTIVETESS_Z */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3276 { /*183, WINED3DRS_ADAPTIVETESS_W */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3277 { /*184, WINED3DRS_ENABLEADAPTIVETESSELLATION */ STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation },
3278 { /*185, WINED3DRS_TWOSIDEDSTENCILMODE */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3279 { /*186, WINED3DRS_CCW_STENCILFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3280 { /*187, WINED3DRS_CCW_STENCILZFAIL */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3281 { /*188, WINED3DRS_CCW_STENCILPASS */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3282 { /*189, WINED3DRS_CCW_STENCILFUNC */ STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil },
3283 { /*190, WINED3DRS_COLORWRITEENABLE1 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3284 { /*191, WINED3DRS_COLORWRITEENABLE2 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3285 { /*192, WINED3DRS_COLORWRITEENABLE3 */ STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite },
3286 { /*193, WINED3DRS_BLENDFACTOR */ STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor },
3287 { /*194, WINED3DRS_SRGBWRITEENABLE */ STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), state_srgbwrite },
3288 { /*195, WINED3DRS_DEPTHBIAS */ STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias },
3289 { /*196, undefined */ 0, state_undefined },
3290 { /*197, undefined */ 0, state_undefined },
3291 { /*198, WINED3DRS_WRAP8 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3292 { /*199, WINED3DRS_WRAP9 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3293 { /*200, WINED3DRS_WRAP10 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3294 { /*201, WINED3DRS_WRAP11 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3295 { /*202, WINED3DRS_WRAP12 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3296 { /*203, WINED3DRS_WRAP13 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3297 { /*204, WINED3DRS_WRAP14 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3298 { /*205, WINED3DRS_WRAP15 */ STATE_RENDER(WINED3DRS_WRAP0), state_wrap },
3299 { /*206, WINED3DRS_SEPARATEALPHABLENDENABLE */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3300 { /*207, WINED3DRS_SRCBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3301 { /*208, WINED3DRS_DESTBLENDALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3302 { /*209, WINED3DRS_BLENDOPALPHA */ STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), state_seperateblend },
3303 /* Texture stage states */
3304 { /*0, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3305 { /*0, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3306 { /*0, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3307 { /*0, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3308 { /*0, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3309 { /*0, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3310 { /*0, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3311 { /*0, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3312 { /*0, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3313 { /*0, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3314 { /*0, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3315 { /*0, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3316 { /*0, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3317 { /*0, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3318 { /*0, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3319 { /*0, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3320 { /*0, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3321 { /*0, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3322 { /*0, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3323 { /*0, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3324 { /*0, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3325 { /*0, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3326 { /*0, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3327 { /*0, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3328 { /*0, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3329 { /*0, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop },
3330 { /*0, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop },
3331 { /*0, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), tex_resultarg },
3332 { /*0, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3333 { /*0, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3334 { /*0, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3335 { /*0, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3337 { /*1, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3338 { /*1, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3339 { /*1, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3340 { /*1, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3341 { /*1, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3342 { /*1, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3343 { /*1, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3344 { /*1, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3345 { /*1, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3346 { /*1, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3347 { /*1, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3348 { /*1, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3349 { /*1, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3350 { /*1, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3351 { /*1, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3352 { /*1, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3353 { /*1, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3354 { /*1, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3355 { /*1, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3356 { /*1, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3357 { /*1, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3358 { /*1, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3359 { /*1, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3360 { /*1, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3361 { /*1, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3362 { /*1, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop },
3363 { /*1, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop },
3364 { /*1, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), tex_resultarg },
3365 { /*1, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3366 { /*1, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3367 { /*1, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3368 { /*1, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3370 { /*2, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3371 { /*2, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3372 { /*2, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3373 { /*2, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3374 { /*2, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3375 { /*2, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3376 { /*2, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3377 { /*2, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3378 { /*2, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3379 { /*2, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3380 { /*2, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3381 { /*2, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3382 { /*2, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3383 { /*2, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3384 { /*2, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3385 { /*2, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3386 { /*2, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3387 { /*2, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3388 { /*2, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3389 { /*2, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3390 { /*2, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3391 { /*2, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3392 { /*2, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3393 { /*2, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3394 { /*2, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3395 { /*2, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop },
3396 { /*2, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop },
3397 { /*2, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), tex_resultarg },
3398 { /*2, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3399 { /*2, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3400 { /*2, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3401 { /*2, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3403 { /*3, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3404 { /*3, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3405 { /*3, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3406 { /*3, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3407 { /*3, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3408 { /*3, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3409 { /*3, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3410 { /*3, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3411 { /*3, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3412 { /*3, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3413 { /*3, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3414 { /*3, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3415 { /*3, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3416 { /*3, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3417 { /*3, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3418 { /*3, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3419 { /*3, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3420 { /*3, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3421 { /*3, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3422 { /*3, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3423 { /*3, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3424 { /*3, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3425 { /*3, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3426 { /*3, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3427 { /*3, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3428 { /*3, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop },
3429 { /*3, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop },
3430 { /*3, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), tex_resultarg },
3431 { /*3, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3432 { /*3, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3433 { /*3, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3434 { /*3, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3436 { /*4, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3437 { /*4, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3438 { /*4, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3439 { /*4, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3440 { /*4, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3441 { /*4, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3442 { /*4, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3443 { /*4, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3444 { /*4, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3445 { /*4, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3446 { /*4, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3447 { /*4, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3448 { /*4, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3449 { /*4, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3450 { /*4, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3451 { /*4, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3452 { /*4, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3453 { /*4, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3454 { /*4, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3455 { /*4, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3456 { /*4, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3457 { /*4, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3458 { /*4, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3459 { /*4, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3460 { /*4, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3461 { /*4, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop },
3462 { /*4, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop },
3463 { /*4, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), tex_resultarg },
3464 { /*4, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3465 { /*4, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3466 { /*4, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3467 { /*4, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3469 { /*5, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3470 { /*5, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3471 { /*5, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3472 { /*5, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3473 { /*5, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3474 { /*5, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3475 { /*5, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3476 { /*5, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3477 { /*5, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3478 { /*5, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3479 { /*5, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3480 { /*5, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3481 { /*5, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3482 { /*5, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3483 { /*5, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3484 { /*5, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3485 { /*5, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3486 { /*5, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3487 { /*5, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3488 { /*5, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3489 { /*5, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3490 { /*5, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3491 { /*5, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3492 { /*5, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3493 { /*5, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3494 { /*5, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop },
3495 { /*5, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop },
3496 { /*5, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), tex_resultarg },
3497 { /*5, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3498 { /*5, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3499 { /*5, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3500 { /*5, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3502 { /*6, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3503 { /*6, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3504 { /*6, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3505 { /*6, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3506 { /*6, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3507 { /*6, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3508 { /*6, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3509 { /*6, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3510 { /*6, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3511 { /*6, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3512 { /*6, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3513 { /*6, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3514 { /*6, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3515 { /*6, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3516 { /*6, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3517 { /*6, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3518 { /*6, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3519 { /*6, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3520 { /*6, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3521 { /*6, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3522 { /*6, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3523 { /*6, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3524 { /*6, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3525 { /*6, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3526 { /*6, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3527 { /*6, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop },
3528 { /*6, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop },
3529 { /*6, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), tex_resultarg },
3530 { /*6, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3531 { /*6, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3532 { /*6, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3533 { /*6, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3535 { /*7, 01, WINED3DTSS_COLOROP */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3536 { /*7, 02, WINED3DTSS_COLORARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3537 { /*7, 03, WINED3DTSS_COLORARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3538 { /*7, 04, WINED3DTSS_ALPHAOP */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3539 { /*7, 05, WINED3DTSS_ALPHAARG1 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3540 { /*7, 06, WINED3DTSS_ALPHAARG2 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3541 { /*7, 07, WINED3DTSS_BUMPENVMAT00 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3542 { /*7, 08, WINED3DTSS_BUMPENVMAT01 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3543 { /*7, 09, WINED3DTSS_BUMPENVMAT10 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3544 { /*7, 10, WINED3DTSS_BUMPENVMAT11 */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), tex_bumpenvmat },
3545 { /*7, 11, WINED3DTSS_TEXCOORDINDEX */ STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex },
3546 { /*7, 12, WINED3DTSS_ADDRESS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3547 { /*7, 13, WINED3DTSS_ADDRESSU */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3548 { /*7, 14, WINED3DTSS_ADDRESSV */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3549 { /*7, 15, WINED3DTSS_BORDERCOLOR */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3550 { /*7, 16, WINED3DTSS_MAGFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3551 { /*7, 17, WINED3DTSS_MINFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3552 { /*7, 18, WINED3DTSS_MIPFILTER */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3553 { /*7, 19, WINED3DTSS_MIPMAPLODBIAS */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3554 { /*7, 20, WINED3DTSS_MAXMIPLEVEL */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3555 { /*7, 21, WINED3DTSS_MAXANISOTROPY */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3556 { /*7, 22, WINED3DTSS_BUMPENVLSCALE */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale },
3557 { /*7, 23, WINED3DTSS_BUMPENVLOFFSET */ STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), tex_bumpenvloffset },
3558 { /*7, 24, WINED3DTSS_TEXTURETRANSFORMFLAGS */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3559 { /*7, 25, WINED3DTSS_ADDRESSW */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3560 { /*7, 26, WINED3DTSS_COLORARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop },
3561 { /*7, 27, WINED3DTSS_ALPHAARG0 */ STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop },
3562 { /*7, 28, WINED3DTSS_RESULTARG */ STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), tex_resultarg },
3563 { /*7, 29, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3564 { /*7, 30, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3565 { /*7, 31, undefined */ 0 /* -> sampler state in ddraw / d3d8 */, state_undefined },
3566 { /*7, 32, WINED3DTSS_CONSTANT */ 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl },
3567 /* Sampler states */
3568 { /* 0, Sampler 0 */ STATE_SAMPLER(0), sampler },
3569 { /* 1, Sampler 1 */ STATE_SAMPLER(1), sampler },
3570 { /* 2, Sampler 2 */ STATE_SAMPLER(2), sampler },
3571 { /* 3, Sampler 3 */ STATE_SAMPLER(3), sampler },
3572 { /* 4, Sampler 3 */ STATE_SAMPLER(4), sampler },
3573 { /* 5, Sampler 5 */ STATE_SAMPLER(5), sampler },
3574 { /* 6, Sampler 6 */ STATE_SAMPLER(6), sampler },
3575 { /* 7, Sampler 7 */ STATE_SAMPLER(7), sampler },
3576 { /* 8, Sampler 8 */ STATE_SAMPLER(8), sampler },
3577 { /* 9, Sampler 9 */ STATE_SAMPLER(9), sampler },
3578 { /*10, Sampler 10 */ STATE_SAMPLER(10), sampler },
3579 { /*11, Sampler 11 */ STATE_SAMPLER(11), sampler },
3580 { /*12, Sampler 12 */ STATE_SAMPLER(12), sampler },
3581 { /*13, Sampler 13 */ STATE_SAMPLER(13), sampler },
3582 { /*14, Sampler 14 */ STATE_SAMPLER(14), sampler },
3583 { /*15, Sampler 15 */ STATE_SAMPLER(15), sampler },
3584 /* Pixel shader */
3585 { /* , Pixel Shader */ STATE_PIXELSHADER, pixelshader },
3586 /* Transform states follow */
3587 { /* 1, undefined */ 0, state_undefined },
3588 { /* 2, WINED3DTS_VIEW */ STATE_TRANSFORM(WINED3DTS_VIEW), transform_view },
3589 { /* 3, WINED3DTS_PROJECTION */ STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection},
3590 { /* 4, undefined */ 0, state_undefined },
3591 { /* 5, undefined */ 0, state_undefined },
3592 { /* 6, undefined */ 0, state_undefined },
3593 { /* 7, undefined */ 0, state_undefined },
3594 { /* 8, undefined */ 0, state_undefined },
3595 { /* 9, undefined */ 0, state_undefined },
3596 { /* 10, undefined */ 0, state_undefined },
3597 { /* 11, undefined */ 0, state_undefined },
3598 { /* 12, undefined */ 0, state_undefined },
3599 { /* 13, undefined */ 0, state_undefined },
3600 { /* 14, undefined */ 0, state_undefined },
3601 { /* 15, undefined */ 0, state_undefined },
3602 { /* 16, WINED3DTS_TEXTURE0 */ STATE_TRANSFORM(WINED3DTS_TEXTURE0), transform_texture },
3603 { /* 17, WINED3DTS_TEXTURE1 */ STATE_TRANSFORM(WINED3DTS_TEXTURE1), transform_texture },
3604 { /* 18, WINED3DTS_TEXTURE2 */ STATE_TRANSFORM(WINED3DTS_TEXTURE2), transform_texture },
3605 { /* 19, WINED3DTS_TEXTURE3 */ STATE_TRANSFORM(WINED3DTS_TEXTURE3), transform_texture },
3606 { /* 20, WINED3DTS_TEXTURE4 */ STATE_TRANSFORM(WINED3DTS_TEXTURE4), transform_texture },
3607 { /* 21, WINED3DTS_TEXTURE5 */ STATE_TRANSFORM(WINED3DTS_TEXTURE5), transform_texture },
3608 { /* 22, WINED3DTS_TEXTURE6 */ STATE_TRANSFORM(WINED3DTS_TEXTURE6), transform_texture },
3609 { /* 23, WINED3DTS_TEXTURE7 */ STATE_TRANSFORM(WINED3DTS_TEXTURE7), transform_texture },
3610 /* A huge gap between TEXTURE7 and WORLDMATRIX(0) :-( But entries are needed to catch then if a broken app sets them */
3611 { /* 24, undefined */ 0, state_undefined },
3612 { /* 25, undefined */ 0, state_undefined },
3613 { /* 26, undefined */ 0, state_undefined },
3614 { /* 27, undefined */ 0, state_undefined },
3615 { /* 28, undefined */ 0, state_undefined },
3616 { /* 29, undefined */ 0, state_undefined },
3617 { /* 30, undefined */ 0, state_undefined },
3618 { /* 31, undefined */ 0, state_undefined },
3619 { /* 32, undefined */ 0, state_undefined },
3620 { /* 33, undefined */ 0, state_undefined },
3621 { /* 34, undefined */ 0, state_undefined },
3622 { /* 35, undefined */ 0, state_undefined },
3623 { /* 36, undefined */ 0, state_undefined },
3624 { /* 37, undefined */ 0, state_undefined },
3625 { /* 38, undefined */ 0, state_undefined },
3626 { /* 39, undefined */ 0, state_undefined },
3627 { /* 40, undefined */ 0, state_undefined },
3628 { /* 41, undefined */ 0, state_undefined },
3629 { /* 42, undefined */ 0, state_undefined },
3630 { /* 43, undefined */ 0, state_undefined },
3631 { /* 44, undefined */ 0, state_undefined },
3632 { /* 45, undefined */ 0, state_undefined },
3633 { /* 46, undefined */ 0, state_undefined },
3634 { /* 47, undefined */ 0, state_undefined },
3635 { /* 48, undefined */ 0, state_undefined },
3636 { /* 49, undefined */ 0, state_undefined },
3637 { /* 50, undefined */ 0, state_undefined },
3638 { /* 51, undefined */ 0, state_undefined },
3639 { /* 52, undefined */ 0, state_undefined },
3640 { /* 53, undefined */ 0, state_undefined },
3641 { /* 54, undefined */ 0, state_undefined },
3642 { /* 55, undefined */ 0, state_undefined },
3643 { /* 56, undefined */ 0, state_undefined },
3644 { /* 57, undefined */ 0, state_undefined },
3645 { /* 58, undefined */ 0, state_undefined },
3646 { /* 59, undefined */ 0, state_undefined },
3647 { /* 60, undefined */ 0, state_undefined },
3648 { /* 61, undefined */ 0, state_undefined },
3649 { /* 62, undefined */ 0, state_undefined },
3650 { /* 63, undefined */ 0, state_undefined },
3651 { /* 64, undefined */ 0, state_undefined },
3652 { /* 65, undefined */ 0, state_undefined },
3653 { /* 66, undefined */ 0, state_undefined },
3654 { /* 67, undefined */ 0, state_undefined },
3655 { /* 68, undefined */ 0, state_undefined },
3656 { /* 69, undefined */ 0, state_undefined },
3657 { /* 70, undefined */ 0, state_undefined },
3658 { /* 71, undefined */ 0, state_undefined },
3659 { /* 72, undefined */ 0, state_undefined },
3660 { /* 73, undefined */ 0, state_undefined },
3661 { /* 74, undefined */ 0, state_undefined },
3662 { /* 75, undefined */ 0, state_undefined },
3663 { /* 76, undefined */ 0, state_undefined },
3664 { /* 77, undefined */ 0, state_undefined },
3665 { /* 78, undefined */ 0, state_undefined },
3666 { /* 79, undefined */ 0, state_undefined },
3667 { /* 80, undefined */ 0, state_undefined },
3668 { /* 81, undefined */ 0, state_undefined },
3669 { /* 82, undefined */ 0, state_undefined },
3670 { /* 83, undefined */ 0, state_undefined },
3671 { /* 84, undefined */ 0, state_undefined },
3672 { /* 85, undefined */ 0, state_undefined },
3673 { /* 86, undefined */ 0, state_undefined },
3674 { /* 87, undefined */ 0, state_undefined },
3675 { /* 88, undefined */ 0, state_undefined },
3676 { /* 89, undefined */ 0, state_undefined },
3677 { /* 90, undefined */ 0, state_undefined },
3678 { /* 91, undefined */ 0, state_undefined },
3679 { /* 92, undefined */ 0, state_undefined },
3680 { /* 93, undefined */ 0, state_undefined },
3681 { /* 94, undefined */ 0, state_undefined },
3682 { /* 95, undefined */ 0, state_undefined },
3683 { /* 96, undefined */ 0, state_undefined },
3684 { /* 97, undefined */ 0, state_undefined },
3685 { /* 98, undefined */ 0, state_undefined },
3686 { /* 99, undefined */ 0, state_undefined },
3687 { /*100, undefined */ 0, state_undefined },
3688 { /*101, undefined */ 0, state_undefined },
3689 { /*102, undefined */ 0, state_undefined },
3690 { /*103, undefined */ 0, state_undefined },
3691 { /*104, undefined */ 0, state_undefined },
3692 { /*105, undefined */ 0, state_undefined },
3693 { /*106, undefined */ 0, state_undefined },
3694 { /*107, undefined */ 0, state_undefined },
3695 { /*108, undefined */ 0, state_undefined },
3696 { /*109, undefined */ 0, state_undefined },
3697 { /*110, undefined */ 0, state_undefined },
3698 { /*111, undefined */ 0, state_undefined },
3699 { /*112, undefined */ 0, state_undefined },
3700 { /*113, undefined */ 0, state_undefined },
3701 { /*114, undefined */ 0, state_undefined },
3702 { /*115, undefined */ 0, state_undefined },
3703 { /*116, undefined */ 0, state_undefined },
3704 { /*117, undefined */ 0, state_undefined },
3705 { /*118, undefined */ 0, state_undefined },
3706 { /*119, undefined */ 0, state_undefined },
3707 { /*120, undefined */ 0, state_undefined },
3708 { /*121, undefined */ 0, state_undefined },
3709 { /*122, undefined */ 0, state_undefined },
3710 { /*123, undefined */ 0, state_undefined },
3711 { /*124, undefined */ 0, state_undefined },
3712 { /*125, undefined */ 0, state_undefined },
3713 { /*126, undefined */ 0, state_undefined },
3714 { /*127, undefined */ 0, state_undefined },
3715 { /*128, undefined */ 0, state_undefined },
3716 { /*129, undefined */ 0, state_undefined },
3717 { /*130, undefined */ 0, state_undefined },
3718 { /*131, undefined */ 0, state_undefined },
3719 { /*132, undefined */ 0, state_undefined },
3720 { /*133, undefined */ 0, state_undefined },
3721 { /*134, undefined */ 0, state_undefined },
3722 { /*135, undefined */ 0, state_undefined },
3723 { /*136, undefined */ 0, state_undefined },
3724 { /*137, undefined */ 0, state_undefined },
3725 { /*138, undefined */ 0, state_undefined },
3726 { /*139, undefined */ 0, state_undefined },
3727 { /*140, undefined */ 0, state_undefined },
3728 { /*141, undefined */ 0, state_undefined },
3729 { /*142, undefined */ 0, state_undefined },
3730 { /*143, undefined */ 0, state_undefined },
3731 { /*144, undefined */ 0, state_undefined },
3732 { /*145, undefined */ 0, state_undefined },
3733 { /*146, undefined */ 0, state_undefined },
3734 { /*147, undefined */ 0, state_undefined },
3735 { /*148, undefined */ 0, state_undefined },
3736 { /*149, undefined */ 0, state_undefined },
3737 { /*150, undefined */ 0, state_undefined },
3738 { /*151, undefined */ 0, state_undefined },
3739 { /*152, undefined */ 0, state_undefined },
3740 { /*153, undefined */ 0, state_undefined },
3741 { /*154, undefined */ 0, state_undefined },
3742 { /*155, undefined */ 0, state_undefined },
3743 { /*156, undefined */ 0, state_undefined },
3744 { /*157, undefined */ 0, state_undefined },
3745 { /*158, undefined */ 0, state_undefined },
3746 { /*159, undefined */ 0, state_undefined },
3747 { /*160, undefined */ 0, state_undefined },
3748 { /*161, undefined */ 0, state_undefined },
3749 { /*162, undefined */ 0, state_undefined },
3750 { /*163, undefined */ 0, state_undefined },
3751 { /*164, undefined */ 0, state_undefined },
3752 { /*165, undefined */ 0, state_undefined },
3753 { /*166, undefined */ 0, state_undefined },
3754 { /*167, undefined */ 0, state_undefined },
3755 { /*168, undefined */ 0, state_undefined },
3756 { /*169, undefined */ 0, state_undefined },
3757 { /*170, undefined */ 0, state_undefined },
3758 { /*171, undefined */ 0, state_undefined },
3759 { /*172, undefined */ 0, state_undefined },
3760 { /*173, undefined */ 0, state_undefined },
3761 { /*174, undefined */ 0, state_undefined },
3762 { /*175, undefined */ 0, state_undefined },
3763 { /*176, undefined */ 0, state_undefined },
3764 { /*177, undefined */ 0, state_undefined },
3765 { /*178, undefined */ 0, state_undefined },
3766 { /*179, undefined */ 0, state_undefined },
3767 { /*180, undefined */ 0, state_undefined },
3768 { /*181, undefined */ 0, state_undefined },
3769 { /*182, undefined */ 0, state_undefined },
3770 { /*183, undefined */ 0, state_undefined },
3771 { /*184, undefined */ 0, state_undefined },
3772 { /*185, undefined */ 0, state_undefined },
3773 { /*186, undefined */ 0, state_undefined },
3774 { /*187, undefined */ 0, state_undefined },
3775 { /*188, undefined */ 0, state_undefined },
3776 { /*189, undefined */ 0, state_undefined },
3777 { /*190, undefined */ 0, state_undefined },
3778 { /*191, undefined */ 0, state_undefined },
3779 { /*192, undefined */ 0, state_undefined },
3780 { /*193, undefined */ 0, state_undefined },
3781 { /*194, undefined */ 0, state_undefined },
3782 { /*195, undefined */ 0, state_undefined },
3783 { /*196, undefined */ 0, state_undefined },
3784 { /*197, undefined */ 0, state_undefined },
3785 { /*198, undefined */ 0, state_undefined },
3786 { /*199, undefined */ 0, state_undefined },
3787 { /*200, undefined */ 0, state_undefined },
3788 { /*201, undefined */ 0, state_undefined },
3789 { /*202, undefined */ 0, state_undefined },
3790 { /*203, undefined */ 0, state_undefined },
3791 { /*204, undefined */ 0, state_undefined },
3792 { /*205, undefined */ 0, state_undefined },
3793 { /*206, undefined */ 0, state_undefined },
3794 { /*207, undefined */ 0, state_undefined },
3795 { /*208, undefined */ 0, state_undefined },
3796 { /*209, undefined */ 0, state_undefined },
3797 { /*210, undefined */ 0, state_undefined },
3798 { /*211, undefined */ 0, state_undefined },
3799 { /*212, undefined */ 0, state_undefined },
3800 { /*213, undefined */ 0, state_undefined },
3801 { /*214, undefined */ 0, state_undefined },
3802 { /*215, undefined */ 0, state_undefined },
3803 { /*216, undefined */ 0, state_undefined },
3804 { /*217, undefined */ 0, state_undefined },
3805 { /*218, undefined */ 0, state_undefined },
3806 { /*219, undefined */ 0, state_undefined },
3807 { /*220, undefined */ 0, state_undefined },
3808 { /*221, undefined */ 0, state_undefined },
3809 { /*222, undefined */ 0, state_undefined },
3810 { /*223, undefined */ 0, state_undefined },
3811 { /*224, undefined */ 0, state_undefined },
3812 { /*225, undefined */ 0, state_undefined },
3813 { /*226, undefined */ 0, state_undefined },
3814 { /*227, undefined */ 0, state_undefined },
3815 { /*228, undefined */ 0, state_undefined },
3816 { /*229, undefined */ 0, state_undefined },
3817 { /*230, undefined */ 0, state_undefined },
3818 { /*231, undefined */ 0, state_undefined },
3819 { /*232, undefined */ 0, state_undefined },
3820 { /*233, undefined */ 0, state_undefined },
3821 { /*234, undefined */ 0, state_undefined },
3822 { /*235, undefined */ 0, state_undefined },
3823 { /*236, undefined */ 0, state_undefined },
3824 { /*237, undefined */ 0, state_undefined },
3825 { /*238, undefined */ 0, state_undefined },
3826 { /*239, undefined */ 0, state_undefined },
3827 { /*240, undefined */ 0, state_undefined },
3828 { /*241, undefined */ 0, state_undefined },
3829 { /*242, undefined */ 0, state_undefined },
3830 { /*243, undefined */ 0, state_undefined },
3831 { /*244, undefined */ 0, state_undefined },
3832 { /*245, undefined */ 0, state_undefined },
3833 { /*246, undefined */ 0, state_undefined },
3834 { /*247, undefined */ 0, state_undefined },
3835 { /*248, undefined */ 0, state_undefined },
3836 { /*249, undefined */ 0, state_undefined },
3837 { /*250, undefined */ 0, state_undefined },
3838 { /*251, undefined */ 0, state_undefined },
3839 { /*252, undefined */ 0, state_undefined },
3840 { /*253, undefined */ 0, state_undefined },
3841 { /*254, undefined */ 0, state_undefined },
3842 { /*255, undefined */ 0, state_undefined },
3843 /* End huge gap */
3844 { /*256, WINED3DTS_WORLDMATRIX(0) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), transform_world },
3845 { /*257, WINED3DTS_WORLDMATRIX(1) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(1)), transform_worldex },
3846 { /*258, WINED3DTS_WORLDMATRIX(2) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(2)), transform_worldex },
3847 { /*259, WINED3DTS_WORLDMATRIX(3) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(3)), transform_worldex },
3848 { /*260, WINED3DTS_WORLDMATRIX(4) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(4)), transform_worldex },
3849 { /*261, WINED3DTS_WORLDMATRIX(5) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(5)), transform_worldex },
3850 { /*262, WINED3DTS_WORLDMATRIX(6) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(6)), transform_worldex },
3851 { /*263, WINED3DTS_WORLDMATRIX(7) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(7)), transform_worldex },
3852 { /*264, WINED3DTS_WORLDMATRIX(8) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(8)), transform_worldex },
3853 { /*265, WINED3DTS_WORLDMATRIX(9) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(9)), transform_worldex },
3854 { /*266, WINED3DTS_WORLDMATRIX(10) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(10)), transform_worldex },
3855 { /*267, WINED3DTS_WORLDMATRIX(11) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(11)), transform_worldex },
3856 { /*268, WINED3DTS_WORLDMATRIX(12) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(12)), transform_worldex },
3857 { /*269, WINED3DTS_WORLDMATRIX(13) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(13)), transform_worldex },
3858 { /*270, WINED3DTS_WORLDMATRIX(14) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(14)), transform_worldex },
3859 { /*271, WINED3DTS_WORLDMATRIX(15) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(15)), transform_worldex },
3860 { /*272, WINED3DTS_WORLDMATRIX(16) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(16)), transform_worldex },
3861 { /*273, WINED3DTS_WORLDMATRIX(17) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(17)), transform_worldex },
3862 { /*274, WINED3DTS_WORLDMATRIX(18) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(18)), transform_worldex },
3863 { /*275, WINED3DTS_WORLDMATRIX(19) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(19)), transform_worldex },
3864 { /*276, WINED3DTS_WORLDMATRIX(20) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(20)), transform_worldex },
3865 { /*277, WINED3DTS_WORLDMATRIX(21) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(21)), transform_worldex },
3866 { /*278, WINED3DTS_WORLDMATRIX(22) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(22)), transform_worldex },
3867 { /*279, WINED3DTS_WORLDMATRIX(23) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(23)), transform_worldex },
3868 { /*280, WINED3DTS_WORLDMATRIX(24) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(24)), transform_worldex },
3869 { /*281, WINED3DTS_WORLDMATRIX(25) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(25)), transform_worldex },
3870 { /*282, WINED3DTS_WORLDMATRIX(26) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(26)), transform_worldex },
3871 { /*283, WINED3DTS_WORLDMATRIX(27) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(27)), transform_worldex },
3872 { /*284, WINED3DTS_WORLDMATRIX(28) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(28)), transform_worldex },
3873 { /*285, WINED3DTS_WORLDMATRIX(29) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(29)), transform_worldex },
3874 { /*286, WINED3DTS_WORLDMATRIX(30) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(30)), transform_worldex },
3875 { /*287, WINED3DTS_WORLDMATRIX(31) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(31)), transform_worldex },
3876 { /*288, WINED3DTS_WORLDMATRIX(32) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(32)), transform_worldex },
3877 { /*289, WINED3DTS_WORLDMATRIX(33) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(33)), transform_worldex },
3878 { /*290, WINED3DTS_WORLDMATRIX(34) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(34)), transform_worldex },
3879 { /*291, WINED3DTS_WORLDMATRIX(35) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(35)), transform_worldex },
3880 { /*292, WINED3DTS_WORLDMATRIX(36) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(36)), transform_worldex },
3881 { /*293, WINED3DTS_WORLDMATRIX(37) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(37)), transform_worldex },
3882 { /*294, WINED3DTS_WORLDMATRIX(38) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(38)), transform_worldex },
3883 { /*295, WINED3DTS_WORLDMATRIX(39) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(39)), transform_worldex },
3884 { /*296, WINED3DTS_WORLDMATRIX(40) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(40)), transform_worldex },
3885 { /*297, WINED3DTS_WORLDMATRIX(41) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(41)), transform_worldex },
3886 { /*298, WINED3DTS_WORLDMATRIX(42) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(42)), transform_worldex },
3887 { /*299, WINED3DTS_WORLDMATRIX(43) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(43)), transform_worldex },
3888 { /*300, WINED3DTS_WORLDMATRIX(44) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(44)), transform_worldex },
3889 { /*301, WINED3DTS_WORLDMATRIX(45) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(45)), transform_worldex },
3890 { /*302, WINED3DTS_WORLDMATRIX(46) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(46)), transform_worldex },
3891 { /*303, WINED3DTS_WORLDMATRIX(47) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(47)), transform_worldex },
3892 { /*304, WINED3DTS_WORLDMATRIX(48) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(48)), transform_worldex },
3893 { /*305, WINED3DTS_WORLDMATRIX(49) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(49)), transform_worldex },
3894 { /*306, WINED3DTS_WORLDMATRIX(50) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(50)), transform_worldex },
3895 { /*307, WINED3DTS_WORLDMATRIX(51) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(51)), transform_worldex },
3896 { /*308, WINED3DTS_WORLDMATRIX(52) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(52)), transform_worldex },
3897 { /*309, WINED3DTS_WORLDMATRIX(53) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(53)), transform_worldex },
3898 { /*310, WINED3DTS_WORLDMATRIX(54) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(54)), transform_worldex },
3899 { /*311, WINED3DTS_WORLDMATRIX(55) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(55)), transform_worldex },
3900 { /*312, WINED3DTS_WORLDMATRIX(56) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(56)), transform_worldex },
3901 { /*313, WINED3DTS_WORLDMATRIX(57) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(57)), transform_worldex },
3902 { /*314, WINED3DTS_WORLDMATRIX(58) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(58)), transform_worldex },
3903 { /*315, WINED3DTS_WORLDMATRIX(59) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(59)), transform_worldex },
3904 { /*316, WINED3DTS_WORLDMATRIX(60) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(60)), transform_worldex },
3905 { /*317, WINED3DTS_WORLDMATRIX(61) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(61)), transform_worldex },
3906 { /*318, WINED3DTS_WORLDMATRIX(62) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(62)), transform_worldex },
3907 { /*319, WINED3DTS_WORLDMATRIX(63) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(63)), transform_worldex },
3908 { /*320, WINED3DTS_WORLDMATRIX(64) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(64)), transform_worldex },
3909 { /*321, WINED3DTS_WORLDMATRIX(65) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(65)), transform_worldex },
3910 { /*322, WINED3DTS_WORLDMATRIX(66) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(66)), transform_worldex },
3911 { /*323, WINED3DTS_WORLDMATRIX(67) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(67)), transform_worldex },
3912 { /*324, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(68)), transform_worldex },
3913 { /*325, WINED3DTS_WORLDMATRIX(68) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(69)), transform_worldex },
3914 { /*326, WINED3DTS_WORLDMATRIX(70) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(70)), transform_worldex },
3915 { /*327, WINED3DTS_WORLDMATRIX(71) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(71)), transform_worldex },
3916 { /*328, WINED3DTS_WORLDMATRIX(72) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(72)), transform_worldex },
3917 { /*329, WINED3DTS_WORLDMATRIX(73) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(73)), transform_worldex },
3918 { /*330, WINED3DTS_WORLDMATRIX(74) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(74)), transform_worldex },
3919 { /*331, WINED3DTS_WORLDMATRIX(75) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(75)), transform_worldex },
3920 { /*332, WINED3DTS_WORLDMATRIX(76) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(76)), transform_worldex },
3921 { /*333, WINED3DTS_WORLDMATRIX(77) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(77)), transform_worldex },
3922 { /*334, WINED3DTS_WORLDMATRIX(78) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(78)), transform_worldex },
3923 { /*335, WINED3DTS_WORLDMATRIX(79) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(79)), transform_worldex },
3924 { /*336, WINED3DTS_WORLDMATRIX(80) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(80)), transform_worldex },
3925 { /*337, WINED3DTS_WORLDMATRIX(81) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(81)), transform_worldex },
3926 { /*338, WINED3DTS_WORLDMATRIX(82) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(82)), transform_worldex },
3927 { /*339, WINED3DTS_WORLDMATRIX(83) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(83)), transform_worldex },
3928 { /*340, WINED3DTS_WORLDMATRIX(84) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(84)), transform_worldex },
3929 { /*341, WINED3DTS_WORLDMATRIX(85) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(85)), transform_worldex },
3930 { /*341, WINED3DTS_WORLDMATRIX(86) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(86)), transform_worldex },
3931 { /*343, WINED3DTS_WORLDMATRIX(87) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(87)), transform_worldex },
3932 { /*344, WINED3DTS_WORLDMATRIX(88) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(88)), transform_worldex },
3933 { /*345, WINED3DTS_WORLDMATRIX(89) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(89)), transform_worldex },
3934 { /*346, WINED3DTS_WORLDMATRIX(90) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(90)), transform_worldex },
3935 { /*347, WINED3DTS_WORLDMATRIX(91) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(91)), transform_worldex },
3936 { /*348, WINED3DTS_WORLDMATRIX(92) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(92)), transform_worldex },
3937 { /*349, WINED3DTS_WORLDMATRIX(93) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(93)), transform_worldex },
3938 { /*350, WINED3DTS_WORLDMATRIX(94) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(94)), transform_worldex },
3939 { /*351, WINED3DTS_WORLDMATRIX(95) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(95)), transform_worldex },
3940 { /*352, WINED3DTS_WORLDMATRIX(96) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(96)), transform_worldex },
3941 { /*353, WINED3DTS_WORLDMATRIX(97) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(97)), transform_worldex },
3942 { /*354, WINED3DTS_WORLDMATRIX(98) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(98)), transform_worldex },
3943 { /*355, WINED3DTS_WORLDMATRIX(99) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(99)), transform_worldex },
3944 { /*356, WINED3DTS_WORLDMATRIX(100) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), transform_worldex },
3945 { /*357, WINED3DTS_WORLDMATRIX(101) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), transform_worldex },
3946 { /*358, WINED3DTS_WORLDMATRIX(102) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), transform_worldex },
3947 { /*359, WINED3DTS_WORLDMATRIX(103) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), transform_worldex },
3948 { /*360, WINED3DTS_WORLDMATRIX(104) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), transform_worldex },
3949 { /*361, WINED3DTS_WORLDMATRIX(105) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), transform_worldex },
3950 { /*362, WINED3DTS_WORLDMATRIX(106) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), transform_worldex },
3951 { /*363, WINED3DTS_WORLDMATRIX(107) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), transform_worldex },
3952 { /*364, WINED3DTS_WORLDMATRIX(108) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), transform_worldex },
3953 { /*365, WINED3DTS_WORLDMATRIX(109) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), transform_worldex },
3954 { /*366, WINED3DTS_WORLDMATRIX(110) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), transform_worldex },
3955 { /*367, WINED3DTS_WORLDMATRIX(111) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), transform_worldex },
3956 { /*368, WINED3DTS_WORLDMATRIX(112) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), transform_worldex },
3957 { /*369, WINED3DTS_WORLDMATRIX(113) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), transform_worldex },
3958 { /*370, WINED3DTS_WORLDMATRIX(114) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), transform_worldex },
3959 { /*371, WINED3DTS_WORLDMATRIX(115) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), transform_worldex },
3960 { /*372, WINED3DTS_WORLDMATRIX(116) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), transform_worldex },
3961 { /*373, WINED3DTS_WORLDMATRIX(117) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), transform_worldex },
3962 { /*374, WINED3DTS_WORLDMATRIX(118) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), transform_worldex },
3963 { /*375, WINED3DTS_WORLDMATRIX(119) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), transform_worldex },
3964 { /*376, WINED3DTS_WORLDMATRIX(120) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), transform_worldex },
3965 { /*377, WINED3DTS_WORLDMATRIX(121) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), transform_worldex },
3966 { /*378, WINED3DTS_WORLDMATRIX(122) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), transform_worldex },
3967 { /*379, WINED3DTS_WORLDMATRIX(123) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), transform_worldex },
3968 { /*380, WINED3DTS_WORLDMATRIX(124) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), transform_worldex },
3969 { /*381, WINED3DTS_WORLDMATRIX(125) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), transform_worldex },
3970 { /*382, WINED3DTS_WORLDMATRIX(126) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), transform_worldex },
3971 { /*383, WINED3DTS_WORLDMATRIX(127) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), transform_worldex },
3972 { /*384, WINED3DTS_WORLDMATRIX(128) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), transform_worldex },
3973 { /*385, WINED3DTS_WORLDMATRIX(129) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), transform_worldex },
3974 { /*386, WINED3DTS_WORLDMATRIX(130) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), transform_worldex },
3975 { /*387, WINED3DTS_WORLDMATRIX(131) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), transform_worldex },
3976 { /*388, WINED3DTS_WORLDMATRIX(132) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), transform_worldex },
3977 { /*389, WINED3DTS_WORLDMATRIX(133) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), transform_worldex },
3978 { /*390, WINED3DTS_WORLDMATRIX(134) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), transform_worldex },
3979 { /*391, WINED3DTS_WORLDMATRIX(135) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), transform_worldex },
3980 { /*392, WINED3DTS_WORLDMATRIX(136) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), transform_worldex },
3981 { /*393, WINED3DTS_WORLDMATRIX(137) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), transform_worldex },
3982 { /*394, WINED3DTS_WORLDMATRIX(138) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), transform_worldex },
3983 { /*395, WINED3DTS_WORLDMATRIX(139) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), transform_worldex },
3984 { /*396, WINED3DTS_WORLDMATRIX(140) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), transform_worldex },
3985 { /*397, WINED3DTS_WORLDMATRIX(141) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), transform_worldex },
3986 { /*398, WINED3DTS_WORLDMATRIX(142) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), transform_worldex },
3987 { /*399, WINED3DTS_WORLDMATRIX(143) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), transform_worldex },
3988 { /*400, WINED3DTS_WORLDMATRIX(144) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), transform_worldex },
3989 { /*401, WINED3DTS_WORLDMATRIX(145) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), transform_worldex },
3990 { /*402, WINED3DTS_WORLDMATRIX(146) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), transform_worldex },
3991 { /*403, WINED3DTS_WORLDMATRIX(147) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), transform_worldex },
3992 { /*404, WINED3DTS_WORLDMATRIX(148) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), transform_worldex },
3993 { /*405, WINED3DTS_WORLDMATRIX(149) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), transform_worldex },
3994 { /*406, WINED3DTS_WORLDMATRIX(150) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), transform_worldex },
3995 { /*407, WINED3DTS_WORLDMATRIX(151) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), transform_worldex },
3996 { /*408, WINED3DTS_WORLDMATRIX(152) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), transform_worldex },
3997 { /*409, WINED3DTS_WORLDMATRIX(153) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), transform_worldex },
3998 { /*410, WINED3DTS_WORLDMATRIX(154) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), transform_worldex },
3999 { /*411, WINED3DTS_WORLDMATRIX(155) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), transform_worldex },
4000 { /*412, WINED3DTS_WORLDMATRIX(156) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), transform_worldex },
4001 { /*413, WINED3DTS_WORLDMATRIX(157) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), transform_worldex },
4002 { /*414, WINED3DTS_WORLDMATRIX(158) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), transform_worldex },
4003 { /*415, WINED3DTS_WORLDMATRIX(159) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), transform_worldex },
4004 { /*416, WINED3DTS_WORLDMATRIX(160) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), transform_worldex },
4005 { /*417, WINED3DTS_WORLDMATRIX(161) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), transform_worldex },
4006 { /*418, WINED3DTS_WORLDMATRIX(162) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), transform_worldex },
4007 { /*419, WINED3DTS_WORLDMATRIX(163) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), transform_worldex },
4008 { /*420, WINED3DTS_WORLDMATRIX(164) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), transform_worldex },
4009 { /*421, WINED3DTS_WORLDMATRIX(165) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), transform_worldex },
4010 { /*422, WINED3DTS_WORLDMATRIX(166) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), transform_worldex },
4011 { /*423, WINED3DTS_WORLDMATRIX(167) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), transform_worldex },
4012 { /*424, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), transform_worldex },
4013 { /*425, WINED3DTS_WORLDMATRIX(168) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), transform_worldex },
4014 { /*426, WINED3DTS_WORLDMATRIX(170) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), transform_worldex },
4015 { /*427, WINED3DTS_WORLDMATRIX(171) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), transform_worldex },
4016 { /*428, WINED3DTS_WORLDMATRIX(172) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), transform_worldex },
4017 { /*429, WINED3DTS_WORLDMATRIX(173) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), transform_worldex },
4018 { /*430, WINED3DTS_WORLDMATRIX(174) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), transform_worldex },
4019 { /*431, WINED3DTS_WORLDMATRIX(175) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), transform_worldex },
4020 { /*432, WINED3DTS_WORLDMATRIX(176) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), transform_worldex },
4021 { /*433, WINED3DTS_WORLDMATRIX(177) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), transform_worldex },
4022 { /*434, WINED3DTS_WORLDMATRIX(178) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), transform_worldex },
4023 { /*435, WINED3DTS_WORLDMATRIX(179) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), transform_worldex },
4024 { /*436, WINED3DTS_WORLDMATRIX(180) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), transform_worldex },
4025 { /*437, WINED3DTS_WORLDMATRIX(181) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), transform_worldex },
4026 { /*438, WINED3DTS_WORLDMATRIX(182) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), transform_worldex },
4027 { /*439, WINED3DTS_WORLDMATRIX(183) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), transform_worldex },
4028 { /*440, WINED3DTS_WORLDMATRIX(184) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), transform_worldex },
4029 { /*441, WINED3DTS_WORLDMATRIX(185) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), transform_worldex },
4030 { /*441, WINED3DTS_WORLDMATRIX(186) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), transform_worldex },
4031 { /*443, WINED3DTS_WORLDMATRIX(187) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), transform_worldex },
4032 { /*444, WINED3DTS_WORLDMATRIX(188) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), transform_worldex },
4033 { /*445, WINED3DTS_WORLDMATRIX(189) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), transform_worldex },
4034 { /*446, WINED3DTS_WORLDMATRIX(190) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), transform_worldex },
4035 { /*447, WINED3DTS_WORLDMATRIX(191) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), transform_worldex },
4036 { /*448, WINED3DTS_WORLDMATRIX(192) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), transform_worldex },
4037 { /*449, WINED3DTS_WORLDMATRIX(193) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), transform_worldex },
4038 { /*450, WINED3DTS_WORLDMATRIX(194) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), transform_worldex },
4039 { /*451, WINED3DTS_WORLDMATRIX(195) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), transform_worldex },
4040 { /*452, WINED3DTS_WORLDMATRIX(196) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), transform_worldex },
4041 { /*453, WINED3DTS_WORLDMATRIX(197) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), transform_worldex },
4042 { /*454, WINED3DTS_WORLDMATRIX(198) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), transform_worldex },
4043 { /*455, WINED3DTS_WORLDMATRIX(199) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), transform_worldex },
4044 { /*356, WINED3DTS_WORLDMATRIX(200) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), transform_worldex },
4045 { /*457, WINED3DTS_WORLDMATRIX(201) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), transform_worldex },
4046 { /*458, WINED3DTS_WORLDMATRIX(202) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), transform_worldex },
4047 { /*459, WINED3DTS_WORLDMATRIX(203) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), transform_worldex },
4048 { /*460, WINED3DTS_WORLDMATRIX(204) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), transform_worldex },
4049 { /*461, WINED3DTS_WORLDMATRIX(205) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), transform_worldex },
4050 { /*462, WINED3DTS_WORLDMATRIX(206) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), transform_worldex },
4051 { /*463, WINED3DTS_WORLDMATRIX(207) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), transform_worldex },
4052 { /*464, WINED3DTS_WORLDMATRIX(208) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), transform_worldex },
4053 { /*465, WINED3DTS_WORLDMATRIX(209) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), transform_worldex },
4054 { /*466, WINED3DTS_WORLDMATRIX(210) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), transform_worldex },
4055 { /*467, WINED3DTS_WORLDMATRIX(211) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), transform_worldex },
4056 { /*468, WINED3DTS_WORLDMATRIX(212) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), transform_worldex },
4057 { /*469, WINED3DTS_WORLDMATRIX(213) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), transform_worldex },
4058 { /*470, WINED3DTS_WORLDMATRIX(214) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), transform_worldex },
4059 { /*471, WINED3DTS_WORLDMATRIX(215) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), transform_worldex },
4060 { /*472, WINED3DTS_WORLDMATRIX(216) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), transform_worldex },
4061 { /*473, WINED3DTS_WORLDMATRIX(217) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), transform_worldex },
4062 { /*474, WINED3DTS_WORLDMATRIX(218) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), transform_worldex },
4063 { /*475, WINED3DTS_WORLDMATRIX(219) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), transform_worldex },
4064 { /*476, WINED3DTS_WORLDMATRIX(220) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), transform_worldex },
4065 { /*477, WINED3DTS_WORLDMATRIX(221) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), transform_worldex },
4066 { /*478, WINED3DTS_WORLDMATRIX(222) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), transform_worldex },
4067 { /*479, WINED3DTS_WORLDMATRIX(223) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), transform_worldex },
4068 { /*480, WINED3DTS_WORLDMATRIX(224) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), transform_worldex },
4069 { /*481, WINED3DTS_WORLDMATRIX(225) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), transform_worldex },
4070 { /*482, WINED3DTS_WORLDMATRIX(226) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), transform_worldex },
4071 { /*483, WINED3DTS_WORLDMATRIX(227) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), transform_worldex },
4072 { /*484, WINED3DTS_WORLDMATRIX(228) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), transform_worldex },
4073 { /*485, WINED3DTS_WORLDMATRIX(229) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), transform_worldex },
4074 { /*486, WINED3DTS_WORLDMATRIX(230) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), transform_worldex },
4075 { /*487, WINED3DTS_WORLDMATRIX(231) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), transform_worldex },
4076 { /*488, WINED3DTS_WORLDMATRIX(232) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), transform_worldex },
4077 { /*489, WINED3DTS_WORLDMATRIX(233) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), transform_worldex },
4078 { /*490, WINED3DTS_WORLDMATRIX(234) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), transform_worldex },
4079 { /*491, WINED3DTS_WORLDMATRIX(235) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), transform_worldex },
4080 { /*492, WINED3DTS_WORLDMATRIX(236) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), transform_worldex },
4081 { /*493, WINED3DTS_WORLDMATRIX(237) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), transform_worldex },
4082 { /*494, WINED3DTS_WORLDMATRIX(238) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), transform_worldex },
4083 { /*495, WINED3DTS_WORLDMATRIX(239) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), transform_worldex },
4084 { /*496, WINED3DTS_WORLDMATRIX(240) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), transform_worldex },
4085 { /*497, WINED3DTS_WORLDMATRIX(241) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), transform_worldex },
4086 { /*498, WINED3DTS_WORLDMATRIX(242) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), transform_worldex },
4087 { /*499, WINED3DTS_WORLDMATRIX(243) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), transform_worldex },
4088 { /*500, WINED3DTS_WORLDMATRIX(244) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), transform_worldex },
4089 { /*501, WINED3DTS_WORLDMATRIX(245) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), transform_worldex },
4090 { /*502, WINED3DTS_WORLDMATRIX(246) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), transform_worldex },
4091 { /*503, WINED3DTS_WORLDMATRIX(247) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), transform_worldex },
4092 { /*504, WINED3DTS_WORLDMATRIX(248) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), transform_worldex },
4093 { /*505, WINED3DTS_WORLDMATRIX(249) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), transform_worldex },
4094 { /*506, WINED3DTS_WORLDMATRIX(250) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), transform_worldex },
4095 { /*507, WINED3DTS_WORLDMATRIX(251) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), transform_worldex },
4096 { /*508, WINED3DTS_WORLDMATRIX(252) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), transform_worldex },
4097 { /*509, WINED3DTS_WORLDMATRIX(253) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), transform_worldex },
4098 { /*510, WINED3DTS_WORLDMATRIX(254) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), transform_worldex },
4099 { /*511, WINED3DTS_WORLDMATRIX(255) */ STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), transform_worldex },
4100 /* Various Vertex states follow */
4101 { /* , STATE_STREAMSRC */ STATE_VDECL, vertexdeclaration },
4102 { /* , STATE_INDEXBUFFER */ STATE_INDEXBUFFER, indexbuffer },
4103 { /* , STATE_VDECL */ STATE_VDECL, vertexdeclaration },
4104 { /* , STATE_VSHADER */ STATE_VDECL, vertexdeclaration },
4105 { /* , STATE_VIEWPORT */ STATE_VIEWPORT, viewport },
4106 { /* , STATE_VERTEXSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4107 { /* , STATE_PIXELSHADERCONSTANT */ STATE_VERTEXSHADERCONSTANT, shaderconstant },
4108 /* Lights */
4109 { /* , STATE_ACTIVELIGHT(0) */ STATE_ACTIVELIGHT(0), light },
4110 { /* , STATE_ACTIVELIGHT(1) */ STATE_ACTIVELIGHT(1), light },
4111 { /* , STATE_ACTIVELIGHT(2) */ STATE_ACTIVELIGHT(2), light },
4112 { /* , STATE_ACTIVELIGHT(3) */ STATE_ACTIVELIGHT(3), light },
4113 { /* , STATE_ACTIVELIGHT(4) */ STATE_ACTIVELIGHT(4), light },
4114 { /* , STATE_ACTIVELIGHT(5) */ STATE_ACTIVELIGHT(5), light },
4115 { /* , STATE_ACTIVELIGHT(6) */ STATE_ACTIVELIGHT(6), light },
4116 { /* , STATE_ACTIVELIGHT(7) */ STATE_ACTIVELIGHT(7), light },
4118 { /* Scissor rect */ STATE_SCISSORRECT, scissorrect }