dpwsockx: Implementation of SPInit
[wine/gsoc_dplay.git] / dlls / wined3d / state.c
blob8ddfd28ba4a4028cd12b2b39ed8307482637537d
1 /*
2 * Direct3D state management
4 * Copyright 2002 Lionel Ulmer
5 * Copyright 2002-2005 Jason Edmeades
6 * Copyright 2003-2004 Raphael Junqueira
7 * Copyright 2004 Christian Costa
8 * Copyright 2005 Oliver Stieber
9 * Copyright 2006 Henri Verbeet
10 * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
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 (*context->gl_info)
39 /* GL locking for state handlers is done by the caller. */
41 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context);
43 static void state_nogl(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
45 /* Used for states which are not mapped to a gl state as-is, but used somehow different,
46 * e.g as a parameter for drawing, or which are unimplemented in windows d3d
48 if(STATE_IS_RENDER(state)) {
49 WINED3DRENDERSTATETYPE RenderState = state - STATE_RENDER(0);
50 TRACE("(%s,%d) no direct mapping to gl\n", debug_d3drenderstate(RenderState), stateblock->renderState[RenderState]);
51 } else {
52 /* Shouldn't have an unknown type here */
53 FIXME("%d no direct mapping to gl of state with unknown type\n", state);
57 static void state_undefined(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
59 ERR("Undefined state.\n");
62 static void state_fillmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
64 WINED3DFILLMODE Value = stateblock->renderState[WINED3DRS_FILLMODE];
66 switch(Value) {
67 case WINED3DFILL_POINT:
68 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
69 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
70 break;
71 case WINED3DFILL_WIREFRAME:
72 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
73 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
74 break;
75 case WINED3DFILL_SOLID:
76 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
77 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
78 break;
79 default:
80 FIXME("Unrecognized WINED3DRS_FILLMODE value %d\n", Value);
84 static void state_lighting(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
86 /* Lighting is not enabled if transformed vertices are drawn
87 * but lighting does not affect the stream sources, so it is not grouped for performance reasons.
88 * This state reads the decoded vertex declaration, so if it is dirty don't do anything. The
89 * vertex declaration applying function calls this function for updating
92 if(isStateDirty(context, STATE_VDECL)) {
93 return;
96 if (stateblock->renderState[WINED3DRS_LIGHTING]
97 && !stateblock->wineD3DDevice->strided_streams.position_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, struct wined3d_context *context)
109 /* No z test without depth stencil buffers */
110 if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) {
111 TRACE("No Z buffer - disabling depth test\n");
112 glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */
113 checkGLcall("glDisable GL_DEPTH_TEST");
114 return;
117 switch ((WINED3DZBUFFERTYPE) stateblock->renderState[WINED3DRS_ZENABLE]) {
118 case WINED3DZB_FALSE:
119 glDisable(GL_DEPTH_TEST);
120 checkGLcall("glDisable GL_DEPTH_TEST");
121 break;
122 case WINED3DZB_TRUE:
123 glEnable(GL_DEPTH_TEST);
124 checkGLcall("glEnable GL_DEPTH_TEST");
125 break;
126 case WINED3DZB_USEW:
127 glEnable(GL_DEPTH_TEST);
128 checkGLcall("glEnable GL_DEPTH_TEST");
129 FIXME("W buffer is not well handled\n");
130 break;
131 default:
132 FIXME("Unrecognized D3DZBUFFERTYPE value %d\n", stateblock->renderState[WINED3DRS_ZENABLE]);
136 static void state_cullmode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
138 /* glFrontFace() is set in context.c at context init and on an offscreen / onscreen rendering
139 * switch
141 switch ((WINED3DCULL) stateblock->renderState[WINED3DRS_CULLMODE]) {
142 case WINED3DCULL_NONE:
143 glDisable(GL_CULL_FACE);
144 checkGLcall("glDisable GL_CULL_FACE");
145 break;
146 case WINED3DCULL_CW:
147 glEnable(GL_CULL_FACE);
148 checkGLcall("glEnable GL_CULL_FACE");
149 glCullFace(GL_FRONT);
150 checkGLcall("glCullFace(GL_FRONT)");
151 break;
152 case WINED3DCULL_CCW:
153 glEnable(GL_CULL_FACE);
154 checkGLcall("glEnable GL_CULL_FACE");
155 glCullFace(GL_BACK);
156 checkGLcall("glCullFace(GL_BACK)");
157 break;
158 default:
159 FIXME("Unrecognized/Unhandled WINED3DCULL value %d\n", stateblock->renderState[WINED3DRS_CULLMODE]);
163 static void state_shademode(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
165 switch ((WINED3DSHADEMODE) stateblock->renderState[WINED3DRS_SHADEMODE]) {
166 case WINED3DSHADE_FLAT:
167 glShadeModel(GL_FLAT);
168 checkGLcall("glShadeModel(GL_FLAT)");
169 break;
170 case WINED3DSHADE_GOURAUD:
171 glShadeModel(GL_SMOOTH);
172 checkGLcall("glShadeModel(GL_SMOOTH)");
173 break;
174 case WINED3DSHADE_PHONG:
175 FIXME("WINED3DSHADE_PHONG isn't supported\n");
176 break;
177 default:
178 FIXME("Unrecognized/Unhandled WINED3DSHADEMODE value %d\n", stateblock->renderState[WINED3DRS_SHADEMODE]);
182 static void state_ditherenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
184 if (stateblock->renderState[WINED3DRS_DITHERENABLE]) {
185 glEnable(GL_DITHER);
186 checkGLcall("glEnable GL_DITHER");
187 } else {
188 glDisable(GL_DITHER);
189 checkGLcall("glDisable GL_DITHER");
193 static void state_zwritenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
195 /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off. If yes,
196 * this has to be merged with ZENABLE and ZFUNC
198 if (stateblock->renderState[WINED3DRS_ZWRITEENABLE]) {
199 glDepthMask(1);
200 checkGLcall("glDepthMask(1)");
201 } else {
202 glDepthMask(0);
203 checkGLcall("glDepthMask(0)");
207 static void state_zfunc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
209 int glParm = CompareFunc(stateblock->renderState[WINED3DRS_ZFUNC]);
211 if(glParm) {
212 if(glParm == GL_EQUAL || glParm == GL_NOTEQUAL) {
213 static BOOL once = FALSE;
214 /* There are a few issues with this: First, our inability to
215 * select a proper Z depth, most of the time we're stuck with
216 * D24S8, even if the app selects D32 or D16. There seem to be
217 * some other precision problems which have to be debugged to
218 * make NOTEQUAL and EQUAL work properly
220 if(!once) {
221 once = TRUE;
222 FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet\n");
226 glDepthFunc(glParm);
227 checkGLcall("glDepthFunc");
231 static void state_ambient(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
233 float col[4];
234 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_AMBIENT], col);
236 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
237 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
238 checkGLcall("glLightModel for MODEL_AMBIENT");
241 static void state_blend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
243 int srcBlend = GL_ZERO;
244 int dstBlend = GL_ZERO;
245 IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
247 /* GL_LINE_SMOOTH needs GL_BLEND to work, according to the red book, and special blending params */
248 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE] ||
249 stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
250 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
252 /* Disable blending in all cases even without pixelshaders. With blending on we could face a big performance penalty.
253 * The d3d9 visual test confirms the behavior. */
254 if (!(target->resource.format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
256 glDisable(GL_BLEND);
257 checkGLcall("glDisable GL_BLEND");
258 return;
259 } else {
260 glEnable(GL_BLEND);
261 checkGLcall("glEnable GL_BLEND");
263 } else {
264 glDisable(GL_BLEND);
265 checkGLcall("glDisable GL_BLEND");
266 /* Nothing more to do - get out */
267 return;
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_DESTCOLOR : dstBlend = GL_DST_COLOR; break;
278 case WINED3DBLEND_INVDESTCOLOR : dstBlend = GL_ONE_MINUS_DST_COLOR; break;
280 /* To compensate the lack of format switching with backbuffer offscreen rendering,
281 * and with onscreen rendering, we modify the alpha test parameters for (INV)DESTALPHA
282 * if the render target doesn't support alpha blending. A nonexistent alpha channel
283 * returns 1.0, so D3DBLEND_DESTALPHA is GL_ONE, and D3DBLEND_INVDESTALPHA is GL_ZERO
285 case WINED3DBLEND_DESTALPHA :
286 dstBlend = target->resource.format_desc->alpha_mask ? GL_DST_ALPHA : GL_ONE;
287 break;
288 case WINED3DBLEND_INVDESTALPHA :
289 dstBlend = target->resource.format_desc->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
290 break;
292 case WINED3DBLEND_SRCALPHASAT :
293 dstBlend = GL_SRC_ALPHA_SATURATE;
294 WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
295 break;
297 /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
298 * values which are still valid up to d3d9. They should not occur as dest blend values
300 case WINED3DBLEND_BOTHSRCALPHA : dstBlend = GL_SRC_ALPHA;
301 srcBlend = GL_SRC_ALPHA;
302 FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
303 break;
305 case WINED3DBLEND_BOTHINVSRCALPHA : dstBlend = GL_ONE_MINUS_SRC_ALPHA;
306 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
307 FIXME("WINED3DRS_DESTBLEND = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
308 break;
310 case WINED3DBLEND_BLENDFACTOR : dstBlend = GL_CONSTANT_COLOR; break;
311 case WINED3DBLEND_INVBLENDFACTOR : dstBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
312 default:
313 FIXME("Unrecognized dst blend value %d\n", stateblock->renderState[WINED3DRS_DESTBLEND]);
316 switch (stateblock->renderState[WINED3DRS_SRCBLEND]) {
317 case WINED3DBLEND_ZERO : srcBlend = GL_ZERO; break;
318 case WINED3DBLEND_ONE : srcBlend = GL_ONE; break;
319 case WINED3DBLEND_SRCCOLOR : srcBlend = GL_SRC_COLOR; break;
320 case WINED3DBLEND_INVSRCCOLOR : srcBlend = GL_ONE_MINUS_SRC_COLOR; break;
321 case WINED3DBLEND_SRCALPHA : srcBlend = GL_SRC_ALPHA; break;
322 case WINED3DBLEND_INVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA; break;
323 case WINED3DBLEND_DESTCOLOR : srcBlend = GL_DST_COLOR; break;
324 case WINED3DBLEND_INVDESTCOLOR : srcBlend = GL_ONE_MINUS_DST_COLOR; break;
325 case WINED3DBLEND_SRCALPHASAT : srcBlend = GL_SRC_ALPHA_SATURATE; break;
327 case WINED3DBLEND_DESTALPHA :
328 srcBlend = target->resource.format_desc->alpha_mask ? GL_DST_ALPHA : GL_ONE;
329 break;
330 case WINED3DBLEND_INVDESTALPHA :
331 srcBlend = target->resource.format_desc->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
332 break;
334 case WINED3DBLEND_BOTHSRCALPHA : srcBlend = GL_SRC_ALPHA;
335 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
336 break;
338 case WINED3DBLEND_BOTHINVSRCALPHA : srcBlend = GL_ONE_MINUS_SRC_ALPHA;
339 dstBlend = GL_SRC_ALPHA;
340 break;
342 case WINED3DBLEND_BLENDFACTOR : srcBlend = GL_CONSTANT_COLOR; break;
343 case WINED3DBLEND_INVBLENDFACTOR : srcBlend = GL_ONE_MINUS_CONSTANT_COLOR; break;
344 default:
345 FIXME("Unrecognized src blend value %d\n", stateblock->renderState[WINED3DRS_SRCBLEND]);
348 if(stateblock->renderState[WINED3DRS_EDGEANTIALIAS] ||
349 stateblock->renderState[WINED3DRS_ANTIALIASEDLINEENABLE]) {
350 glEnable(GL_LINE_SMOOTH);
351 checkGLcall("glEnable(GL_LINE_SMOOTH)");
352 if(srcBlend != GL_SRC_ALPHA) {
353 WARN("WINED3DRS_EDGEANTIALIAS enabled, but unexpected src blending param\n");
355 if(dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE) {
356 WARN("WINED3DRS_EDGEANTIALIAS enabled, but unexpected dst blending param\n");
358 } else {
359 glDisable(GL_LINE_SMOOTH);
360 checkGLcall("glDisable(GL_LINE_SMOOTH)");
363 /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
364 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_BLENDOP))) {
365 state_blendop(STATE_RENDER(WINED3DRS_BLENDOPALPHA), stateblock, context);
368 if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]) {
369 int srcBlendAlpha = GL_ZERO;
370 int dstBlendAlpha = GL_ZERO;
372 /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
373 if(!GL_SUPPORT(EXT_BLEND_FUNC_SEPARATE)) {
374 WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
375 return;
378 switch (stateblock->renderState[WINED3DRS_DESTBLENDALPHA]) {
379 case WINED3DBLEND_ZERO : dstBlendAlpha = GL_ZERO; break;
380 case WINED3DBLEND_ONE : dstBlendAlpha = GL_ONE; break;
381 case WINED3DBLEND_SRCCOLOR : dstBlendAlpha = GL_SRC_COLOR; break;
382 case WINED3DBLEND_INVSRCCOLOR : dstBlendAlpha = GL_ONE_MINUS_SRC_COLOR; break;
383 case WINED3DBLEND_SRCALPHA : dstBlendAlpha = GL_SRC_ALPHA; break;
384 case WINED3DBLEND_INVSRCALPHA : dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; break;
385 case WINED3DBLEND_DESTCOLOR : dstBlendAlpha = GL_DST_COLOR; break;
386 case WINED3DBLEND_INVDESTCOLOR : dstBlendAlpha = GL_ONE_MINUS_DST_COLOR; break;
387 case WINED3DBLEND_DESTALPHA : dstBlendAlpha = GL_DST_ALPHA; break;
388 case WINED3DBLEND_INVDESTALPHA : dstBlendAlpha = GL_DST_ALPHA; break;
389 case WINED3DBLEND_SRCALPHASAT :
390 dstBlend = GL_SRC_ALPHA_SATURATE;
391 WARN("Application uses SRCALPHASAT as dest blend factor, expect problems\n");
392 break;
393 /* WINED3DBLEND_BOTHSRCALPHA and WINED3DBLEND_BOTHINVSRCALPHA are legacy source blending
394 * values which are still valid up to d3d9. They should not occur as dest blend values
396 case WINED3DBLEND_BOTHSRCALPHA :
397 dstBlendAlpha = GL_SRC_ALPHA;
398 srcBlendAlpha = GL_SRC_ALPHA;
399 FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHSRCALPHA, what to do?\n");
400 break;
401 case WINED3DBLEND_BOTHINVSRCALPHA :
402 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
403 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
404 FIXME("WINED3DRS_DESTBLENDALPHA = WINED3DBLEND_BOTHINVSRCALPHA, what to do?\n");
405 break;
406 case WINED3DBLEND_BLENDFACTOR : dstBlendAlpha = GL_CONSTANT_COLOR; break;
407 case WINED3DBLEND_INVBLENDFACTOR : dstBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR; break;
408 default:
409 FIXME("Unrecognized dst blend alpha value %d\n", stateblock->renderState[WINED3DRS_DESTBLENDALPHA]);
412 switch (stateblock->renderState[WINED3DRS_SRCBLENDALPHA]) {
413 case WINED3DBLEND_ZERO : srcBlendAlpha = GL_ZERO; break;
414 case WINED3DBLEND_ONE : srcBlendAlpha = GL_ONE; break;
415 case WINED3DBLEND_SRCCOLOR : srcBlendAlpha = GL_SRC_COLOR; break;
416 case WINED3DBLEND_INVSRCCOLOR : srcBlendAlpha = GL_ONE_MINUS_SRC_COLOR; break;
417 case WINED3DBLEND_SRCALPHA : srcBlendAlpha = GL_SRC_ALPHA; break;
418 case WINED3DBLEND_INVSRCALPHA : srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA; break;
419 case WINED3DBLEND_DESTCOLOR : srcBlendAlpha = GL_DST_COLOR; break;
420 case WINED3DBLEND_INVDESTCOLOR : srcBlendAlpha = GL_ONE_MINUS_DST_COLOR; break;
421 case WINED3DBLEND_SRCALPHASAT : srcBlendAlpha = GL_SRC_ALPHA_SATURATE; break;
422 case WINED3DBLEND_DESTALPHA : srcBlendAlpha = GL_DST_ALPHA; break;
423 case WINED3DBLEND_INVDESTALPHA : srcBlendAlpha = GL_DST_ALPHA; break;
424 case WINED3DBLEND_BOTHSRCALPHA :
425 srcBlendAlpha = GL_SRC_ALPHA;
426 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
427 break;
428 case WINED3DBLEND_BOTHINVSRCALPHA :
429 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
430 dstBlendAlpha = GL_SRC_ALPHA;
431 break;
432 case WINED3DBLEND_BLENDFACTOR : srcBlendAlpha = GL_CONSTANT_COLOR; break;
433 case WINED3DBLEND_INVBLENDFACTOR : srcBlendAlpha = GL_ONE_MINUS_CONSTANT_COLOR; break;
434 default:
435 FIXME("Unrecognized src blend alpha value %d\n", stateblock->renderState[WINED3DRS_SRCBLENDALPHA]);
438 GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
439 checkGLcall("glBlendFuncSeparateEXT");
440 } else {
441 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
442 glBlendFunc(srcBlend, dstBlend);
443 checkGLcall("glBlendFunc");
446 /* colorkey fixup for stage 0 alphaop depends on WINED3DRS_ALPHABLENDENABLE state,
447 so it may need updating */
448 if (stateblock->renderState[WINED3DRS_COLORKEYENABLE]) {
449 const struct StateEntry *StateTable = stateblock->wineD3DDevice->StateTable;
450 StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
454 static void state_blendfactor_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
456 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
459 static void state_blendfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
461 float col[4];
463 TRACE("Setting BlendFactor to %d\n", stateblock->renderState[WINED3DRS_BLENDFACTOR]);
464 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_BLENDFACTOR], col);
465 GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
466 checkGLcall("glBlendColor");
469 static void state_alpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
471 int glParm = 0;
472 float ref;
473 BOOL enable_ckey = FALSE;
475 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
477 /* Find out if the texture on the first stage has a ckey set
478 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
479 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
480 * used WINED3DRS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
481 * in case it finds some texture+colorkeyenable combination which needs extra care.
483 if (stateblock->textures[0])
485 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
487 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
489 IWineD3DSurfaceImpl *surf;
491 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *)stateblock->textures[0])->surfaces[0];
493 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
495 /* The surface conversion does not do color keying conversion for surfaces that have an alpha
496 * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
497 * surface has alpha bits */
498 if (!surf->resource.format_desc->alpha_mask) enable_ckey = TRUE;
503 if(enable_ckey || context->last_was_ckey) {
504 const struct StateEntry *StateTable = stateblock->wineD3DDevice->StateTable;
505 StateTable[STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP)].apply(STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), stateblock, context);
507 context->last_was_ckey = enable_ckey;
509 if (stateblock->renderState[WINED3DRS_ALPHATESTENABLE] ||
510 (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey)) {
511 glEnable(GL_ALPHA_TEST);
512 checkGLcall("glEnable GL_ALPHA_TEST");
513 } else {
514 glDisable(GL_ALPHA_TEST);
515 checkGLcall("glDisable GL_ALPHA_TEST");
516 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
517 * enable call
519 return;
522 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && enable_ckey) {
523 glParm = GL_NOTEQUAL;
524 ref = 0.0f;
525 } else {
526 ref = ((float) stateblock->renderState[WINED3DRS_ALPHAREF]) / 255.0f;
527 glParm = CompareFunc(stateblock->renderState[WINED3DRS_ALPHAFUNC]);
529 if(glParm) {
530 glAlphaFunc(glParm, ref);
531 checkGLcall("glAlphaFunc");
535 static void state_clipping(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
537 DWORD enable = 0xFFFFFFFF;
538 DWORD disable = 0x00000000;
540 if (!stateblock->wineD3DDevice->vs_clipping && use_vs(stateblock))
542 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
543 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
544 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
545 * of that - don't do anything here and keep them disabled
547 if(stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
548 static BOOL warned = FALSE;
549 if(!warned) {
550 FIXME("Clipping not supported with vertex shaders\n");
551 warned = TRUE;
554 return;
557 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
558 * of already set values
561 /* If enabling / disabling all
562 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
564 if (stateblock->renderState[WINED3DRS_CLIPPING]) {
565 enable = stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
566 disable = ~stateblock->renderState[WINED3DRS_CLIPPLANEENABLE];
567 if(GL_SUPPORT(NV_DEPTH_CLAMP)) {
568 glDisable(GL_DEPTH_CLAMP_NV);
569 checkGLcall("glDisable(GL_DEPTH_CLAMP_NV)");
571 } else {
572 disable = 0xffffffff;
573 enable = 0x00;
574 if(GL_SUPPORT(NV_DEPTH_CLAMP)) {
575 glEnable(GL_DEPTH_CLAMP_NV);
576 checkGLcall("glEnable(GL_DEPTH_CLAMP_NV)");
580 if (enable & WINED3DCLIPPLANE0) { glEnable(GL_CLIP_PLANE0); checkGLcall("glEnable(clip plane 0)"); }
581 if (enable & WINED3DCLIPPLANE1) { glEnable(GL_CLIP_PLANE1); checkGLcall("glEnable(clip plane 1)"); }
582 if (enable & WINED3DCLIPPLANE2) { glEnable(GL_CLIP_PLANE2); checkGLcall("glEnable(clip plane 2)"); }
583 if (enable & WINED3DCLIPPLANE3) { glEnable(GL_CLIP_PLANE3); checkGLcall("glEnable(clip plane 3)"); }
584 if (enable & WINED3DCLIPPLANE4) { glEnable(GL_CLIP_PLANE4); checkGLcall("glEnable(clip plane 4)"); }
585 if (enable & WINED3DCLIPPLANE5) { glEnable(GL_CLIP_PLANE5); checkGLcall("glEnable(clip plane 5)"); }
587 if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
588 if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
589 if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
590 if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
591 if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
592 if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
594 /** update clipping status */
595 if (enable) {
596 stateblock->clip_status.ClipUnion = 0;
597 stateblock->clip_status.ClipIntersection = 0xFFFFFFFF;
598 } else {
599 stateblock->clip_status.ClipUnion = 0;
600 stateblock->clip_status.ClipIntersection = 0;
604 static void state_blendop_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
606 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
609 static void state_blendop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
611 int blendEquation = GL_FUNC_ADD;
612 int blendEquationAlpha = GL_FUNC_ADD;
614 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
615 if(stateblock->renderState[WINED3DRS_BLENDOPALPHA] && !GL_SUPPORT(EXT_BLEND_EQUATION_SEPARATE)) {
616 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
617 return;
620 switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOP]) {
621 case WINED3DBLENDOP_ADD : blendEquation = GL_FUNC_ADD; break;
622 case WINED3DBLENDOP_SUBTRACT : blendEquation = GL_FUNC_SUBTRACT; break;
623 case WINED3DBLENDOP_REVSUBTRACT : blendEquation = GL_FUNC_REVERSE_SUBTRACT; break;
624 case WINED3DBLENDOP_MIN : blendEquation = GL_MIN; break;
625 case WINED3DBLENDOP_MAX : blendEquation = GL_MAX; break;
626 default:
627 FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOP]);
630 switch ((WINED3DBLENDOP) stateblock->renderState[WINED3DRS_BLENDOPALPHA]) {
631 case WINED3DBLENDOP_ADD : blendEquationAlpha = GL_FUNC_ADD; break;
632 case WINED3DBLENDOP_SUBTRACT : blendEquationAlpha = GL_FUNC_SUBTRACT; break;
633 case WINED3DBLENDOP_REVSUBTRACT : blendEquationAlpha = GL_FUNC_REVERSE_SUBTRACT; break;
634 case WINED3DBLENDOP_MIN : blendEquationAlpha = GL_MIN; break;
635 case WINED3DBLENDOP_MAX : blendEquationAlpha = GL_MAX; break;
636 default:
637 FIXME("Unrecognized/Unhandled D3DBLENDOP value %d\n", stateblock->renderState[WINED3DRS_BLENDOPALPHA]);
640 if(stateblock->renderState[WINED3DRS_SEPARATEALPHABLENDENABLE]) {
641 TRACE("glBlendEquationSeparateEXT(%x, %x)\n", blendEquation, blendEquationAlpha);
642 GL_EXTCALL(glBlendEquationSeparateEXT(blendEquation, blendEquationAlpha));
643 checkGLcall("glBlendEquationSeparateEXT");
644 } else {
645 TRACE("glBlendEquation(%x)\n", blendEquation);
646 GL_EXTCALL(glBlendEquationEXT(blendEquation));
647 checkGLcall("glBlendEquation");
651 static void state_specularenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
653 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
654 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
655 * specular color. This is wrong:
656 * Separate specular color means the specular colour is maintained separately, whereas
657 * single color means it is merged in. However in both cases they are being used to
658 * some extent.
659 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
660 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
661 * running 1.4 yet!
664 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
665 * Instead, we need to setup the FinalCombiner properly.
667 * The default setup for the FinalCombiner is:
669 * <variable> <input> <mapping> <usage>
670 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
671 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
672 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
673 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
674 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
675 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
676 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
678 * That's pretty much fine as it is, except for variable B, which needs to take
679 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
680 * whether WINED3DRS_SPECULARENABLE is enabled or not.
683 TRACE("Setting specular enable state and materials\n");
684 if (stateblock->renderState[WINED3DRS_SPECULARENABLE]) {
685 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*) &stateblock->material.Specular);
686 checkGLcall("glMaterialfv");
688 if(stateblock->material.Power > GL_LIMITS(shininess)) {
689 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
690 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
691 * allows bigger values. If the extension is supported, GL_LIMITS(shininess) contains the
692 * value reported by the extension, otherwise 128. For values > GL_LIMITS(shininess) clamp
693 * them, it should be safe to do so without major visual distortions.
695 WARN("Material power = %f, limit %f\n", stateblock->material.Power, GL_LIMITS(shininess));
696 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, GL_LIMITS(shininess));
697 } else {
698 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, stateblock->material.Power);
700 checkGLcall("glMaterialf(GL_SHININESS)");
702 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
703 glEnable(GL_COLOR_SUM_EXT);
704 } else {
705 TRACE("Specular colors cannot be enabled in this version of opengl\n");
707 checkGLcall("glEnable(GL_COLOR_SUM)");
709 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
710 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
711 checkGLcall("glFinalCombinerInputNV()");
713 } else {
714 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
716 /* for the case of enabled lighting: */
717 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
718 checkGLcall("glMaterialfv");
720 /* for the case of disabled lighting: */
721 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
722 glDisable(GL_COLOR_SUM_EXT);
723 } else {
724 TRACE("Specular colors cannot be disabled in this version of opengl\n");
726 checkGLcall("glDisable(GL_COLOR_SUM)");
728 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
729 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
730 checkGLcall("glFinalCombinerInputNV()");
734 TRACE("(%p) : Diffuse (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Diffuse.r, stateblock->material.Diffuse.g,
735 stateblock->material.Diffuse.b, stateblock->material.Diffuse.a);
736 TRACE("(%p) : Ambient (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Ambient.r, stateblock->material.Ambient.g,
737 stateblock->material.Ambient.b, stateblock->material.Ambient.a);
738 TRACE("(%p) : Specular (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Specular.r, stateblock->material.Specular.g,
739 stateblock->material.Specular.b, stateblock->material.Specular.a);
740 TRACE("(%p) : Emissive (%f,%f,%f,%f)\n", stateblock->wineD3DDevice, stateblock->material.Emissive.r, stateblock->material.Emissive.g,
741 stateblock->material.Emissive.b, stateblock->material.Emissive.a);
743 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*) &stateblock->material.Ambient);
744 checkGLcall("glMaterialfv(GL_AMBIENT)");
745 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*) &stateblock->material.Diffuse);
746 checkGLcall("glMaterialfv(GL_DIFFUSE)");
747 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*) &stateblock->material.Emissive);
748 checkGLcall("glMaterialfv(GL_EMISSION)");
751 static void state_texfactor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
753 unsigned int i;
755 /* Note the texture color applies to all textures whereas
756 * GL_TEXTURE_ENV_COLOR applies to active only
758 float col[4];
759 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_TEXTUREFACTOR], col);
761 /* And now the default texture color as well */
762 for (i = 0; i < GL_LIMITS(texture_stages); i++) {
763 /* Note the WINED3DRS value applies to all textures, but GL has one
764 * per texture, so apply it now ready to be used!
766 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + i));
767 checkGLcall("glActiveTextureARB");
769 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
770 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
774 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
775 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
777 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
778 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
779 GL_EXTCALL(glActiveStencilFaceEXT(face));
780 checkGLcall("glActiveStencilFaceEXT(...)");
781 glStencilFunc(func, ref, mask);
782 checkGLcall("glStencilFunc(...)");
783 glStencilOp(stencilFail, depthFail, stencilPass);
784 checkGLcall("glStencilOp(...)");
787 static void state_stencil(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
789 DWORD onesided_enable = FALSE;
790 DWORD twosided_enable = FALSE;
791 GLint func = GL_ALWAYS;
792 GLint func_ccw = GL_ALWAYS;
793 GLint ref = 0;
794 GLuint mask = 0;
795 GLint stencilFail = GL_KEEP;
796 GLint depthFail = GL_KEEP;
797 GLint stencilPass = GL_KEEP;
798 GLint stencilFail_ccw = GL_KEEP;
799 GLint depthFail_ccw = GL_KEEP;
800 GLint stencilPass_ccw = GL_KEEP;
802 /* No stencil test without a stencil buffer */
803 if(stateblock->wineD3DDevice->stencilBufferTarget == NULL) {
804 glDisable(GL_STENCIL_TEST);
805 checkGLcall("glDisable GL_STENCIL_TEST");
806 return;
809 onesided_enable = stateblock->renderState[WINED3DRS_STENCILENABLE];
810 twosided_enable = stateblock->renderState[WINED3DRS_TWOSIDEDSTENCILMODE];
811 if( !( func = CompareFunc(stateblock->renderState[WINED3DRS_STENCILFUNC]) ) )
812 func = GL_ALWAYS;
813 if( !( func_ccw = CompareFunc(stateblock->renderState[WINED3DRS_CCW_STENCILFUNC]) ) )
814 func_ccw = GL_ALWAYS;
815 ref = stateblock->renderState[WINED3DRS_STENCILREF];
816 mask = stateblock->renderState[WINED3DRS_STENCILMASK];
817 stencilFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILFAIL]);
818 depthFail = StencilOp(stateblock->renderState[WINED3DRS_STENCILZFAIL]);
819 stencilPass = StencilOp(stateblock->renderState[WINED3DRS_STENCILPASS]);
820 stencilFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILFAIL]);
821 depthFail_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILZFAIL]);
822 stencilPass_ccw = StencilOp(stateblock->renderState[WINED3DRS_CCW_STENCILPASS]);
824 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
825 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
826 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
827 onesided_enable, twosided_enable, ref, mask,
828 func, stencilFail, depthFail, stencilPass,
829 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
831 if (twosided_enable && onesided_enable) {
832 glEnable(GL_STENCIL_TEST);
833 checkGLcall("glEnable GL_STENCIL_TEST");
835 if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
836 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
837 * which has an effect on the code below too. If we apply the front face
838 * afterwards, we are sure that the active stencil face is set to front,
839 * and other stencil functions which do not use two sided stencil do not have
840 * to set it back
842 renderstate_stencil_twosided(context, GL_BACK,
843 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
844 renderstate_stencil_twosided(context, GL_FRONT,
845 func, ref, mask, stencilFail, depthFail, stencilPass);
846 } else if(GL_SUPPORT(ATI_SEPARATE_STENCIL)) {
847 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
848 checkGLcall("glStencilFuncSeparateATI(...)");
849 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
850 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
851 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
852 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
853 } else {
854 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
856 } else if(onesided_enable) {
857 if(GL_SUPPORT(EXT_STENCIL_TWO_SIDE)) {
858 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
859 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
862 /* This code disables the ATI extension as well, since the standard stencil functions are equal
863 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
865 glEnable(GL_STENCIL_TEST);
866 checkGLcall("glEnable GL_STENCIL_TEST");
867 glStencilFunc(func, ref, mask);
868 checkGLcall("glStencilFunc(...)");
869 glStencilOp(stencilFail, depthFail, stencilPass);
870 checkGLcall("glStencilOp(...)");
871 } else {
872 glDisable(GL_STENCIL_TEST);
873 checkGLcall("glDisable GL_STENCIL_TEST");
877 static void state_stencilwrite2s(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
879 DWORD mask;
881 if(stateblock->wineD3DDevice->stencilBufferTarget) {
882 mask = stateblock->renderState[WINED3DRS_STENCILWRITEMASK];
883 } else {
884 mask = 0;
887 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
888 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
889 glStencilMask(mask);
890 checkGLcall("glStencilMask");
891 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
892 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
893 glStencilMask(mask);
896 static void state_stencilwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
898 DWORD mask;
900 if(stateblock->wineD3DDevice->stencilBufferTarget) {
901 mask = stateblock->renderState[WINED3DRS_STENCILWRITEMASK];
902 } else {
903 mask = 0;
906 glStencilMask(mask);
907 checkGLcall("glStencilMask");
910 static void state_fog_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
913 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
915 if (!stateblock->renderState[WINED3DRS_FOGENABLE]) return;
917 /* Table fog on: Never use fog coords, and use per-fragment fog */
918 if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] != WINED3DFOG_NONE) {
919 glHint(GL_FOG_HINT, GL_NICEST);
920 if(context->fog_coord) {
921 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
922 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
923 context->fog_coord = FALSE;
925 return;
928 /* Otherwise use per-vertex fog in any case */
929 glHint(GL_FOG_HINT, GL_FASTEST);
931 if(stateblock->renderState[WINED3DRS_FOGVERTEXMODE] == WINED3DFOG_NONE || context->last_was_rhw) {
932 /* No fog at all, or transformed vertices: Use fog coord */
933 if(!context->fog_coord) {
934 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
935 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
936 context->fog_coord = TRUE;
938 } else {
939 /* Otherwise, use the fragment depth */
940 if(context->fog_coord) {
941 glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
942 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
943 context->fog_coord = FALSE;
948 void state_fogstartend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
950 float fogstart, fogend;
951 union {
952 DWORD d;
953 float f;
954 } tmpvalue;
956 switch(context->fog_source) {
957 case FOGSOURCE_VS:
958 fogstart = 1.0f;
959 fogend = 0.0f;
960 break;
962 case FOGSOURCE_COORD:
963 fogstart = 255.0f;
964 fogend = 0.0f;
965 break;
967 case FOGSOURCE_FFP:
968 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGSTART];
969 fogstart = tmpvalue.f;
970 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGEND];
971 fogend = tmpvalue.f;
972 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
973 if(fogstart == fogend) {
974 fogstart = -1.0f / 0.0f;
975 fogend = 0.0f;
977 break;
979 default:
980 /* This should not happen.context->fog_source is set in wined3d, not the app.
981 * Still this is needed to make the compiler happy
983 ERR("Unexpected fog coordinate source\n");
984 fogstart = 0.0f;
985 fogend = 0.0f;
988 glFogf(GL_FOG_START, fogstart);
989 checkGLcall("glFogf(GL_FOG_START, fogstart)");
990 TRACE("Fog Start == %f\n", fogstart);
992 glFogf(GL_FOG_END, fogend);
993 checkGLcall("glFogf(GL_FOG_END, fogend)");
994 TRACE("Fog End == %f\n", fogend);
997 void state_fog_fragpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
999 enum fogsource new_source;
1001 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
1003 if (!stateblock->renderState[WINED3DRS_FOGENABLE]) {
1004 /* No fog? Disable it, and we're done :-) */
1005 glDisableWINE(GL_FOG);
1006 checkGLcall("glDisable GL_FOG");
1007 return;
1010 /* Fog Rules:
1012 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1013 * It can use the Z value of the vertex, or the alpha component of the specular color.
1014 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1015 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1016 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1018 * FOGTABLEMODE != NONE:
1019 * The Z value is used, with the equation specified, no matter what vertex type.
1021 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1022 * Per vertex fog is calculated using the specified fog equation and the parameters
1024 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1025 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1026 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1029 * Rules for vertex fog with shaders:
1031 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1032 * the fog computation to happen during transformation while openGL expects it to happen
1033 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1034 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1035 * To solve this problem, WineD3D does:
1036 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1037 * shader,
1038 * and 2) disables the fog computation (in either the fixed function or programmable
1039 * rasterizer) if using a vertex program.
1041 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1042 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1043 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1044 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1045 * There are some GL differences between specular fog coords and vertex shaders though.
1047 * With table fog the vertex shader fog coordinate is ignored.
1049 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1050 * without shaders).
1053 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1054 * the system will apply only pixel(=table) fog effects."
1056 if(stateblock->renderState[WINED3DRS_FOGTABLEMODE] == WINED3DFOG_NONE) {
1057 if(use_vs(stateblock)) {
1058 glFogi(GL_FOG_MODE, GL_LINEAR);
1059 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1060 new_source = FOGSOURCE_VS;
1061 } else {
1062 switch (stateblock->renderState[WINED3DRS_FOGVERTEXMODE]) {
1063 /* If processed vertices are used, fall through to the NONE case */
1064 case WINED3DFOG_EXP:
1065 if(!context->last_was_rhw) {
1066 glFogi(GL_FOG_MODE, GL_EXP);
1067 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1068 new_source = FOGSOURCE_FFP;
1069 break;
1071 /* drop through */
1073 case WINED3DFOG_EXP2:
1074 if(!context->last_was_rhw) {
1075 glFogi(GL_FOG_MODE, GL_EXP2);
1076 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1077 new_source = FOGSOURCE_FFP;
1078 break;
1080 /* drop through */
1082 case WINED3DFOG_LINEAR:
1083 if(!context->last_was_rhw) {
1084 glFogi(GL_FOG_MODE, GL_LINEAR);
1085 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1086 new_source = FOGSOURCE_FFP;
1087 break;
1089 /* drop through */
1091 case WINED3DFOG_NONE:
1092 /* Both are none? According to msdn the alpha channel of the specular
1093 * color contains a fog factor. Set it in drawStridedSlow.
1094 * Same happens with Vertexfog on transformed vertices
1096 new_source = FOGSOURCE_COORD;
1097 glFogi(GL_FOG_MODE, GL_LINEAR);
1098 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1099 break;
1101 default:
1102 FIXME("Unexpected WINED3DRS_FOGVERTEXMODE %d\n", stateblock->renderState[WINED3DRS_FOGVERTEXMODE]);
1103 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1106 } else {
1107 new_source = FOGSOURCE_FFP;
1109 switch (stateblock->renderState[WINED3DRS_FOGTABLEMODE]) {
1110 case WINED3DFOG_EXP:
1111 glFogi(GL_FOG_MODE, GL_EXP);
1112 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1113 break;
1115 case WINED3DFOG_EXP2:
1116 glFogi(GL_FOG_MODE, GL_EXP2);
1117 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1118 break;
1120 case WINED3DFOG_LINEAR:
1121 glFogi(GL_FOG_MODE, GL_LINEAR);
1122 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1123 break;
1125 case WINED3DFOG_NONE: /* Won't happen */
1126 default:
1127 FIXME("Unexpected WINED3DRS_FOGTABLEMODE %d\n", stateblock->renderState[WINED3DRS_FOGTABLEMODE]);
1131 glEnableWINE(GL_FOG);
1132 checkGLcall("glEnable GL_FOG");
1133 if(new_source != context->fog_source) {
1134 context->fog_source = new_source;
1135 state_fogstartend(STATE_RENDER(WINED3DRS_FOGSTART), stateblock, context);
1139 static void state_rangefog_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1141 if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
1142 WARN("Range fog enabled, but not supported by this opengl implementation\n");
1146 static void state_rangefog(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1148 if(stateblock->renderState[WINED3DRS_RANGEFOGENABLE]) {
1149 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1150 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1151 } else {
1152 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1153 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1157 void state_fogcolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1159 float col[4];
1160 D3DCOLORTOGLFLOAT4(stateblock->renderState[WINED3DRS_FOGCOLOR], col);
1161 glFogfv(GL_FOG_COLOR, &col[0]);
1162 checkGLcall("glFog GL_FOG_COLOR");
1165 void state_fogdensity(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1167 union {
1168 DWORD d;
1169 float f;
1170 } tmpvalue;
1171 tmpvalue.d = stateblock->renderState[WINED3DRS_FOGDENSITY];
1172 glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1173 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1176 static void state_colormat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1178 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
1179 GLenum Parm = 0;
1181 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1182 * The vertex declaration will call this function if the fixed function pipeline is used.
1185 if(isStateDirty(context, STATE_VDECL)) {
1186 return;
1189 context->num_untracked_materials = 0;
1190 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1191 && stateblock->renderState[WINED3DRS_COLORVERTEX])
1193 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1194 stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE],
1195 stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE],
1196 stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE],
1197 stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE]);
1199 if (stateblock->renderState[WINED3DRS_DIFFUSEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1200 if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1201 Parm = GL_AMBIENT_AND_DIFFUSE;
1202 } else {
1203 Parm = GL_DIFFUSE;
1205 if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1206 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1207 context->num_untracked_materials++;
1209 if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1210 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1211 context->num_untracked_materials++;
1213 } else if (stateblock->renderState[WINED3DRS_AMBIENTMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1214 Parm = GL_AMBIENT;
1215 if(stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1216 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1217 context->num_untracked_materials++;
1219 if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1220 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1221 context->num_untracked_materials++;
1223 } else if (stateblock->renderState[WINED3DRS_EMISSIVEMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1224 Parm = GL_EMISSION;
1225 if(stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1226 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1227 context->num_untracked_materials++;
1229 } else if (stateblock->renderState[WINED3DRS_SPECULARMATERIALSOURCE] == WINED3DMCS_COLOR1) {
1230 Parm = GL_SPECULAR;
1234 /* Nothing changed, return. */
1235 if (Parm == context->tracking_parm) return;
1237 if(!Parm) {
1238 glDisable(GL_COLOR_MATERIAL);
1239 checkGLcall("glDisable GL_COLOR_MATERIAL");
1240 } else {
1241 glColorMaterial(GL_FRONT_AND_BACK, Parm);
1242 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1243 glEnable(GL_COLOR_MATERIAL);
1244 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1247 /* Apparently calls to glMaterialfv are ignored for properties we're
1248 * tracking with glColorMaterial, so apply those here. */
1249 switch (context->tracking_parm) {
1250 case GL_AMBIENT_AND_DIFFUSE:
1251 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1252 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1253 checkGLcall("glMaterialfv");
1254 break;
1256 case GL_DIFFUSE:
1257 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&device->updateStateBlock->material.Diffuse);
1258 checkGLcall("glMaterialfv");
1259 break;
1261 case GL_AMBIENT:
1262 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&device->updateStateBlock->material.Ambient);
1263 checkGLcall("glMaterialfv");
1264 break;
1266 case GL_EMISSION:
1267 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float*)&device->updateStateBlock->material.Emissive);
1268 checkGLcall("glMaterialfv");
1269 break;
1271 case GL_SPECULAR:
1272 /* Only change material color if specular is enabled, otherwise it is set to black */
1273 if (device->stateBlock->renderState[WINED3DRS_SPECULARENABLE]) {
1274 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&device->updateStateBlock->material.Specular);
1275 checkGLcall("glMaterialfv");
1276 } else {
1277 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1278 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1279 checkGLcall("glMaterialfv");
1281 break;
1284 context->tracking_parm = Parm;
1287 static void state_linepattern(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1289 union {
1290 DWORD d;
1291 WINED3DLINEPATTERN lp;
1292 } tmppattern;
1293 tmppattern.d = stateblock->renderState[WINED3DRS_LINEPATTERN];
1295 TRACE("Line pattern: repeat %d bits %x\n", tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1297 if (tmppattern.lp.wRepeatFactor) {
1298 glLineStipple(tmppattern.lp.wRepeatFactor, tmppattern.lp.wLinePattern);
1299 checkGLcall("glLineStipple(repeat, linepattern)");
1300 glEnable(GL_LINE_STIPPLE);
1301 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1302 } else {
1303 glDisable(GL_LINE_STIPPLE);
1304 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1308 static void state_zbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1310 union {
1311 DWORD d;
1312 float f;
1313 } tmpvalue;
1315 if (stateblock->renderState[WINED3DRS_ZBIAS]) {
1316 tmpvalue.d = stateblock->renderState[WINED3DRS_ZBIAS];
1317 TRACE("ZBias value %f\n", tmpvalue.f);
1318 glPolygonOffset(0, -tmpvalue.f);
1319 checkGLcall("glPolygonOffset(0, -Value)");
1320 glEnable(GL_POLYGON_OFFSET_FILL);
1321 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL);");
1322 glEnable(GL_POLYGON_OFFSET_LINE);
1323 checkGLcall("glEnable(GL_POLYGON_OFFSET_LINE);");
1324 glEnable(GL_POLYGON_OFFSET_POINT);
1325 checkGLcall("glEnable(GL_POLYGON_OFFSET_POINT);");
1326 } else {
1327 glDisable(GL_POLYGON_OFFSET_FILL);
1328 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL);");
1329 glDisable(GL_POLYGON_OFFSET_LINE);
1330 checkGLcall("glDisable(GL_POLYGON_OFFSET_LINE);");
1331 glDisable(GL_POLYGON_OFFSET_POINT);
1332 checkGLcall("glDisable(GL_POLYGON_OFFSET_POINT);");
1337 static void state_normalize(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1339 if(isStateDirty(context, STATE_VDECL)) {
1340 return;
1342 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1343 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1344 * by zero and is not properly defined in opengl, so avoid it
1346 if (stateblock->renderState[WINED3DRS_NORMALIZENORMALS]
1347 && (stateblock->wineD3DDevice->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1349 glEnable(GL_NORMALIZE);
1350 checkGLcall("glEnable(GL_NORMALIZE);");
1351 } else {
1352 glDisable(GL_NORMALIZE);
1353 checkGLcall("glDisable(GL_NORMALIZE);");
1357 static void state_psizemin_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1359 union {
1360 DWORD d;
1361 float f;
1362 } tmpvalue;
1364 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1365 if (tmpvalue.f != 1.0f)
1367 FIXME("WINED3DRS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1369 tmpvalue.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1370 if (tmpvalue.f != 64.0f)
1372 FIXME("WINED3DRS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1377 static void state_psizemin_ext(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1379 union {
1380 DWORD d;
1381 float f;
1382 } min, max;
1384 min.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1385 max.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1387 /* Max point size trumps min point size */
1388 if(min.f > max.f) {
1389 min.f = max.f;
1392 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1393 checkGLcall("glPointParameterfEXT(...)");
1394 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1395 checkGLcall("glPointParameterfEXT(...)");
1398 static void state_psizemin_arb(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1400 union {
1401 DWORD d;
1402 float f;
1403 } min, max;
1405 min.d = stateblock->renderState[WINED3DRS_POINTSIZE_MIN];
1406 max.d = stateblock->renderState[WINED3DRS_POINTSIZE_MAX];
1408 /* Max point size trumps min point size */
1409 if(min.f > max.f) {
1410 min.f = max.f;
1413 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1414 checkGLcall("glPointParameterfARB(...)");
1415 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1416 checkGLcall("glPointParameterfARB(...)");
1419 static void state_pscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1421 /* TODO: Group this with the viewport */
1423 * POINTSCALEENABLE controls how point size value is treated. If set to
1424 * true, the point size is scaled with respect to height of viewport.
1425 * When set to false point size is in pixels.
1428 /* Default values */
1429 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1430 union {
1431 DWORD d;
1432 float f;
1433 } pointSize, A, B, C;
1435 pointSize.d = stateblock->renderState[WINED3DRS_POINTSIZE];
1436 A.d = stateblock->renderState[WINED3DRS_POINTSCALE_A];
1437 B.d = stateblock->renderState[WINED3DRS_POINTSCALE_B];
1438 C.d = stateblock->renderState[WINED3DRS_POINTSCALE_C];
1440 if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1441 GLfloat scaleFactor;
1442 float h = stateblock->viewport.Height;
1444 if(pointSize.f < GL_LIMITS(pointsizemin)) {
1446 * Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1447 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1448 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1449 * are less than 1.0f. scale_factor = 1.0f / point_size.
1451 scaleFactor = pointSize.f / GL_LIMITS(pointsizemin);
1452 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1453 * is 1.0, but then accepts points below that and draws too small points
1455 pointSize.f = GL_LIMITS(pointsizemin);
1456 } else if(pointSize.f > GL_LIMITS(pointsize)) {
1457 /* gl already scales the input to glPointSize,
1458 * d3d scales the result after the point size scale.
1459 * If the point size is bigger than the max size, use the
1460 * scaling to scale it bigger, and set the gl point size to max
1462 scaleFactor = pointSize.f / GL_LIMITS(pointsize);
1463 TRACE("scale: %f\n", scaleFactor);
1464 pointSize.f = GL_LIMITS(pointsize);
1465 } else {
1466 scaleFactor = 1.0f;
1468 scaleFactor = pow(h * scaleFactor, 2);
1470 att[0] = A.f / scaleFactor;
1471 att[1] = B.f / scaleFactor;
1472 att[2] = C.f / scaleFactor;
1475 if(GL_SUPPORT(ARB_POINT_PARAMETERS)) {
1476 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1477 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1479 else if(GL_SUPPORT(EXT_POINT_PARAMETERS)) {
1480 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1481 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1482 } else if(stateblock->renderState[WINED3DRS_POINTSCALEENABLE]) {
1483 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1486 glPointSize(pointSize.f);
1487 checkGLcall("glPointSize(...);");
1490 static void state_debug_monitor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1492 WARN("token: %#x\n", stateblock->renderState[WINED3DRS_DEBUGMONITORTOKEN]);
1495 static void state_colorwrite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1497 DWORD Value = stateblock->renderState[WINED3DRS_COLORWRITEENABLE];
1499 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1500 Value & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1501 Value & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1502 Value & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1503 Value & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1504 glColorMask(Value & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1505 Value & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1506 Value & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1507 Value & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1508 checkGLcall("glColorMask(...)");
1510 /* depends on WINED3DRS_COLORWRITEENABLE. */
1511 if(stateblock->renderState[WINED3DRS_COLORWRITEENABLE1] != 0x0000000F ||
1512 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2] != 0x0000000F ||
1513 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3] != 0x0000000F ) {
1514 ERR("(WINED3DRS_COLORWRITEENABLE1/2/3,%d,%d,%d) not yet implemented. Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n",
1515 stateblock->renderState[WINED3DRS_COLORWRITEENABLE1],
1516 stateblock->renderState[WINED3DRS_COLORWRITEENABLE2],
1517 stateblock->renderState[WINED3DRS_COLORWRITEENABLE3]);
1521 static void state_localviewer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1523 if(stateblock->renderState[WINED3DRS_LOCALVIEWER]) {
1524 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1525 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1526 } else {
1527 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1528 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1532 static void state_lastpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1534 if(stateblock->renderState[WINED3DRS_LASTPIXEL]) {
1535 TRACE("Last Pixel Drawing Enabled\n");
1536 } else {
1537 static BOOL warned;
1538 if (!warned) {
1539 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1540 warned = TRUE;
1541 } else {
1542 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1547 static void state_pointsprite_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1549 BOOL warned = FALSE;
1550 /* TODO: NV_POINT_SPRITE */
1551 if (!warned && stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1552 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1553 FIXME("Point sprites not supported\n");
1554 warned = TRUE;
1558 static void state_pointsprite(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1560 if (stateblock->renderState[WINED3DRS_POINTSPRITEENABLE]) {
1561 BOOL warned = FALSE;
1562 if(GL_LIMITS(point_sprite_units) < GL_LIMITS(textures) && !warned) {
1563 if(use_ps(stateblock) || stateblock->lowest_disabled_stage > GL_LIMITS(point_sprite_units)) {
1564 FIXME("The app uses point sprite texture coordinates on more units than supported by the driver\n");
1565 warned = TRUE;
1569 glEnable(GL_POINT_SPRITE_ARB);
1570 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1571 } else {
1572 glDisable(GL_POINT_SPRITE_ARB);
1573 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1577 static void state_wrap(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1580 http://www.cosc.brocku.ca/Offerings/3P98/course/lectures/texture/
1581 http://www.gamedev.net/reference/programming/features/rendererdll3/page2.asp
1582 Discussion on the ways to turn on WRAPing to solve an OpenGL conversion problem.
1583 http://www.flipcode.org/cgi-bin/fcmsg.cgi?thread_show=10248
1585 so far as I can tell, wrapping and texture-coordinate generate go hand in hand,
1587 TRACE("Stub\n");
1588 if(stateblock->renderState[WINED3DRS_WRAP0] ||
1589 stateblock->renderState[WINED3DRS_WRAP1] ||
1590 stateblock->renderState[WINED3DRS_WRAP2] ||
1591 stateblock->renderState[WINED3DRS_WRAP3] ||
1592 stateblock->renderState[WINED3DRS_WRAP4] ||
1593 stateblock->renderState[WINED3DRS_WRAP5] ||
1594 stateblock->renderState[WINED3DRS_WRAP6] ||
1595 stateblock->renderState[WINED3DRS_WRAP7] ||
1596 stateblock->renderState[WINED3DRS_WRAP8] ||
1597 stateblock->renderState[WINED3DRS_WRAP9] ||
1598 stateblock->renderState[WINED3DRS_WRAP10] ||
1599 stateblock->renderState[WINED3DRS_WRAP11] ||
1600 stateblock->renderState[WINED3DRS_WRAP12] ||
1601 stateblock->renderState[WINED3DRS_WRAP13] ||
1602 stateblock->renderState[WINED3DRS_WRAP14] ||
1603 stateblock->renderState[WINED3DRS_WRAP15] ) {
1604 FIXME("(WINED3DRS_WRAP0) Texture wraping not yet supported\n");
1608 static void state_msaa_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1610 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1611 WARN("Multisample antialiasing not supported by gl\n");
1615 static void state_msaa(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1617 if(stateblock->renderState[WINED3DRS_MULTISAMPLEANTIALIAS]) {
1618 glEnable(GL_MULTISAMPLE_ARB);
1619 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1620 } else {
1621 glDisable(GL_MULTISAMPLE_ARB);
1622 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1626 static void state_scissor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1628 if(stateblock->renderState[WINED3DRS_SCISSORTESTENABLE]) {
1629 glEnable(GL_SCISSOR_TEST);
1630 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1631 } else {
1632 glDisable(GL_SCISSOR_TEST);
1633 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1637 static void state_depthbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1639 union {
1640 DWORD d;
1641 float f;
1642 } tmpvalue;
1644 if(stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS] ||
1645 stateblock->renderState[WINED3DRS_DEPTHBIAS]) {
1646 tmpvalue.d = stateblock->renderState[WINED3DRS_SLOPESCALEDEPTHBIAS];
1647 glEnable(GL_POLYGON_OFFSET_FILL);
1648 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1649 glPolygonOffset(tmpvalue.f, *((float*)&stateblock->renderState[WINED3DRS_DEPTHBIAS]));
1650 checkGLcall("glPolygonOffset(...)");
1651 } else {
1652 glDisable(GL_POLYGON_OFFSET_FILL);
1653 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1657 static void state_perspective(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1659 if (stateblock->renderState[WINED3DRS_TEXTUREPERSPECTIVE]) {
1660 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1661 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1662 } else {
1663 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1664 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1668 static void state_stippledalpha(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1670 TRACE("Stub\n");
1671 if (stateblock->renderState[WINED3DRS_STIPPLEDALPHA])
1672 FIXME(" Stippled Alpha not supported yet.\n");
1675 static void state_antialias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1677 TRACE("Stub\n");
1678 if (stateblock->renderState[WINED3DRS_ANTIALIAS])
1679 FIXME(" Antialias not supported yet.\n");
1682 static void state_multisampmask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1684 TRACE("Stub\n");
1685 if (stateblock->renderState[WINED3DRS_MULTISAMPLEMASK] != 0xFFFFFFFF)
1686 FIXME("(WINED3DRS_MULTISAMPLEMASK,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_MULTISAMPLEMASK]);
1689 static void state_patchedgestyle(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1691 TRACE("Stub\n");
1692 if (stateblock->renderState[WINED3DRS_PATCHEDGESTYLE] != WINED3DPATCHEDGE_DISCRETE)
1693 FIXME("(WINED3DRS_PATCHEDGESTYLE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_PATCHEDGESTYLE]);
1696 static void state_patchsegments(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1698 union {
1699 DWORD d;
1700 float f;
1701 } tmpvalue;
1702 tmpvalue.f = 1.0f;
1704 TRACE("Stub\n");
1705 if (stateblock->renderState[WINED3DRS_PATCHSEGMENTS] != tmpvalue.d)
1707 static BOOL displayed = FALSE;
1709 tmpvalue.d = stateblock->renderState[WINED3DRS_PATCHSEGMENTS];
1710 if(!displayed)
1711 FIXME("(WINED3DRS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1713 displayed = TRUE;
1717 static void state_positiondegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1719 TRACE("Stub\n");
1720 if (stateblock->renderState[WINED3DRS_POSITIONDEGREE] != WINED3DDEGREE_CUBIC)
1721 FIXME("(WINED3DRS_POSITIONDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_POSITIONDEGREE]);
1724 static void state_normaldegree(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1726 TRACE("Stub\n");
1727 if (stateblock->renderState[WINED3DRS_NORMALDEGREE] != WINED3DDEGREE_LINEAR)
1728 FIXME("(WINED3DRS_NORMALDEGREE,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_NORMALDEGREE]);
1731 static void state_tessellation(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1733 TRACE("Stub\n");
1734 if(stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION])
1735 FIXME("(WINED3DRS_ENABLEADAPTIVETESSELLATION,%d) not yet implemented\n", stateblock->renderState[WINED3DRS_ENABLEADAPTIVETESSELLATION]);
1738 static void state_wrapu(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1740 if(stateblock->renderState[WINED3DRS_WRAPU]) {
1741 FIXME("Render state WINED3DRS_WRAPU not implemented yet\n");
1745 static void state_wrapv(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1747 if(stateblock->renderState[WINED3DRS_WRAPV]) {
1748 FIXME("Render state WINED3DRS_WRAPV not implemented yet\n");
1752 static void state_monoenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1754 if(stateblock->renderState[WINED3DRS_MONOENABLE]) {
1755 FIXME("Render state WINED3DRS_MONOENABLE not implemented yet\n");
1759 static void state_rop2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1761 if(stateblock->renderState[WINED3DRS_ROP2]) {
1762 FIXME("Render state WINED3DRS_ROP2 not implemented yet\n");
1766 static void state_planemask(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1768 if(stateblock->renderState[WINED3DRS_PLANEMASK]) {
1769 FIXME("Render state WINED3DRS_PLANEMASK not implemented yet\n");
1773 static void state_subpixel(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1775 if(stateblock->renderState[WINED3DRS_SUBPIXEL]) {
1776 FIXME("Render state WINED3DRS_SUBPIXEL not implemented yet\n");
1780 static void state_subpixelx(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1782 if(stateblock->renderState[WINED3DRS_SUBPIXELX]) {
1783 FIXME("Render state WINED3DRS_SUBPIXELX not implemented yet\n");
1787 static void state_stippleenable(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1789 if(stateblock->renderState[WINED3DRS_STIPPLEENABLE]) {
1790 FIXME("Render state WINED3DRS_STIPPLEENABLE not implemented yet\n");
1794 static void state_bordercolor(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1796 if(stateblock->renderState[WINED3DRS_BORDERCOLOR]) {
1797 FIXME("Render state WINED3DRS_BORDERCOLOR not implemented yet\n");
1801 static void state_mipmaplodbias(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1803 if(stateblock->renderState[WINED3DRS_MIPMAPLODBIAS]) {
1804 FIXME("Render state WINED3DRS_MIPMAPLODBIAS not implemented yet\n");
1808 static void state_anisotropy(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1810 if(stateblock->renderState[WINED3DRS_ANISOTROPY]) {
1811 FIXME("Render state WINED3DRS_ANISOTROPY not implemented yet\n");
1815 static void state_flushbatch(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1817 if(stateblock->renderState[WINED3DRS_FLUSHBATCH]) {
1818 FIXME("Render state WINED3DRS_FLUSHBATCH not implemented yet\n");
1822 static void state_translucentsi(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1824 if(stateblock->renderState[WINED3DRS_TRANSLUCENTSORTINDEPENDENT]) {
1825 FIXME("Render state WINED3DRS_TRANSLUCENTSORTINDEPENDENT not implemented yet\n");
1829 static void state_extents(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1831 if(stateblock->renderState[WINED3DRS_EXTENTS]) {
1832 FIXME("Render state WINED3DRS_EXTENTS not implemented yet\n");
1836 static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
1838 if(stateblock->renderState[WINED3DRS_COLORKEYBLENDENABLE]) {
1839 FIXME("Render state WINED3DRS_COLORKEYBLENDENABLE not implemented yet\n");
1843 /* Set texture operations up - The following avoids lots of ifdefs in this routine!*/
1844 #if defined (GL_VERSION_1_3)
1845 # define useext(A) A
1846 #elif defined (GL_EXT_texture_env_combine)
1847 # define useext(A) A##_EXT
1848 #elif defined (GL_ARB_texture_env_combine)
1849 # define useext(A) A##_ARB
1850 #endif
1852 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
1853 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
1854 * input should be used for all input components. The WINED3DTA_COMPLEMENT
1855 * flag specifies the complement of the input should be used. */
1856 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
1857 BOOL complement = arg & WINED3DTA_COMPLEMENT;
1859 /* Calculate the operand */
1860 if (complement) {
1861 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
1862 else *operand = GL_ONE_MINUS_SRC_COLOR;
1863 } else {
1864 if (from_alpha) *operand = GL_SRC_ALPHA;
1865 else *operand = GL_SRC_COLOR;
1868 /* Calculate the source */
1869 switch (arg & WINED3DTA_SELECTMASK) {
1870 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
1871 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
1872 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
1873 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
1874 case WINED3DTA_SPECULAR:
1876 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
1877 * 'Secondary color' and isn't supported until base GL supports it
1878 * There is no concept of temp registers as far as I can tell
1880 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
1881 *source = GL_TEXTURE;
1882 break;
1883 default:
1884 FIXME("Unrecognized texture arg %#x\n", arg);
1885 *source = GL_TEXTURE;
1886 break;
1890 /* Setup the texture operations texture stage states */
1891 static void set_tex_op(const struct wined3d_context *context, IWineD3DDevice *iface,
1892 BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3)
1894 GLenum src1, src2, src3;
1895 GLenum opr1, opr2, opr3;
1896 GLenum comb_target;
1897 GLenum src0_target, src1_target, src2_target;
1898 GLenum opr0_target, opr1_target, opr2_target;
1899 GLenum scal_target;
1900 GLenum opr=0, invopr, src3_target, opr3_target;
1901 BOOL Handled = FALSE;
1902 IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
1904 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
1906 /* This is called by a state handler which has the gl lock held and a context for the thread */
1908 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
1909 the form (a1 <operation> a2). However, some of the more complex operations
1910 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
1911 in a third parameter called a0. Therefore these are operations of the form
1912 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
1914 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
1915 functions below, expect their syntax to differ slightly to those listed in the
1916 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
1917 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
1919 if (isAlpha) {
1920 comb_target = useext(GL_COMBINE_ALPHA);
1921 src0_target = useext(GL_SOURCE0_ALPHA);
1922 src1_target = useext(GL_SOURCE1_ALPHA);
1923 src2_target = useext(GL_SOURCE2_ALPHA);
1924 opr0_target = useext(GL_OPERAND0_ALPHA);
1925 opr1_target = useext(GL_OPERAND1_ALPHA);
1926 opr2_target = useext(GL_OPERAND2_ALPHA);
1927 scal_target = GL_ALPHA_SCALE;
1929 else {
1930 comb_target = useext(GL_COMBINE_RGB);
1931 src0_target = useext(GL_SOURCE0_RGB);
1932 src1_target = useext(GL_SOURCE1_RGB);
1933 src2_target = useext(GL_SOURCE2_RGB);
1934 opr0_target = useext(GL_OPERAND0_RGB);
1935 opr1_target = useext(GL_OPERAND1_RGB);
1936 opr2_target = useext(GL_OPERAND2_RGB);
1937 scal_target = useext(GL_RGB_SCALE);
1940 /* If a texture stage references an invalid texture unit the stage just
1941 * passes through the result from the previous stage */
1942 if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) {
1943 arg1 = WINED3DTA_CURRENT;
1944 op = WINED3DTOP_SELECTARG1;
1947 if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) {
1948 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
1949 } else {
1950 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
1952 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
1953 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
1955 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
1957 Handled = TRUE; /* Assume will be handled */
1959 /* Other texture operations require special extensions: */
1960 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
1961 if (isAlpha) {
1962 opr = GL_SRC_ALPHA;
1963 invopr = GL_ONE_MINUS_SRC_ALPHA;
1964 src3_target = GL_SOURCE3_ALPHA_NV;
1965 opr3_target = GL_OPERAND3_ALPHA_NV;
1966 } else {
1967 opr = GL_SRC_COLOR;
1968 invopr = GL_ONE_MINUS_SRC_COLOR;
1969 src3_target = GL_SOURCE3_RGB_NV;
1970 opr3_target = GL_OPERAND3_RGB_NV;
1972 switch (op) {
1973 case WINED3DTOP_DISABLE: /* Only for alpha */
1974 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1975 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
1976 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
1977 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
1978 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
1979 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
1980 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
1981 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
1982 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
1983 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
1984 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
1985 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
1986 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
1987 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
1988 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
1989 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
1990 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
1991 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
1992 break;
1993 case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */
1994 case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */
1995 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
1996 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
1997 if (op == WINED3DTOP_SELECTARG1) {
1998 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
1999 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2000 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2001 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2002 } else {
2003 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2004 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2005 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2006 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2008 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2009 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2010 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2011 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2012 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2013 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2014 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2015 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2016 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2017 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2018 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2019 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2020 break;
2022 case WINED3DTOP_MODULATE:
2023 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2024 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2025 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2026 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2027 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2028 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2029 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2030 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2031 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2032 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2033 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2034 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2035 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2036 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2037 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2038 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2039 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2040 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2041 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2042 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2043 break;
2044 case WINED3DTOP_MODULATE2X:
2045 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2046 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2047 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2048 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2049 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2050 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2051 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2052 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2053 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2054 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2055 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2056 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2057 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2058 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2059 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2060 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2061 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2062 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2063 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2064 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2065 break;
2066 case WINED3DTOP_MODULATE4X:
2067 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2068 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2069 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2070 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2071 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2072 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2073 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2074 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2075 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2076 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2077 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2078 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2079 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2080 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2081 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2082 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2083 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2084 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2085 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2086 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2087 break;
2089 case WINED3DTOP_ADD:
2090 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2091 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2092 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2093 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2094 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2095 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2096 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2097 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2098 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2099 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2100 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2101 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2102 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2103 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2104 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2105 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2106 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2107 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2108 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2109 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2110 break;
2112 case WINED3DTOP_ADDSIGNED:
2113 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2114 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2115 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2116 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2117 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2118 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2119 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2120 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2121 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2122 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2123 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2124 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2125 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2126 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2127 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2128 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2129 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2130 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2131 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2132 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2133 break;
2135 case WINED3DTOP_ADDSIGNED2X:
2136 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2137 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2138 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2139 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2140 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2141 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2142 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2143 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2144 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2145 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2146 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2147 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2148 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2149 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2150 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2151 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2152 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2153 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2154 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2155 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2156 break;
2158 case WINED3DTOP_ADDSMOOTH:
2159 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2160 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2161 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2162 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2163 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2164 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2165 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2166 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2167 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2168 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2169 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2170 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2171 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2172 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2173 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2174 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2175 switch (opr1) {
2176 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2177 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2178 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2179 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2181 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2182 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2183 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2184 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2185 break;
2187 case WINED3DTOP_BLENDDIFFUSEALPHA:
2188 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2189 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2190 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2191 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2192 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2193 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2194 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR));
2195 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)");
2196 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2197 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2198 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2199 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2200 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2201 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2202 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR));
2203 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)");
2204 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2205 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2206 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2207 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2208 break;
2209 case WINED3DTOP_BLENDTEXTUREALPHA:
2210 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2211 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2212 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2213 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2214 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2215 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2216 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2217 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2218 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2219 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2220 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2221 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2222 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2223 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2224 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2225 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2226 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2227 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2228 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2229 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2230 break;
2231 case WINED3DTOP_BLENDFACTORALPHA:
2232 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2233 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2234 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2235 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2236 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2237 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2238 glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT));
2239 checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)");
2240 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2241 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2242 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2243 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2244 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2245 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2246 glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT));
2247 checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)");
2248 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2249 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2250 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2251 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2252 break;
2253 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2254 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2255 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2256 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2257 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2258 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2259 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2260 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2261 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2262 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2263 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2264 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2265 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2266 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2267 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2268 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2269 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2270 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2271 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2272 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2273 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2274 break;
2275 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2276 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2277 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2278 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2279 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2280 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2281 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2282 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2283 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2284 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2285 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2286 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2287 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2288 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2289 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2290 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2291 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2292 switch (opr) {
2293 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2294 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2296 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2297 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2298 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2299 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2300 break;
2301 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2302 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2303 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2304 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2305 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2306 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2307 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2308 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2309 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2310 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2311 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2312 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2313 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2314 switch (opr1) {
2315 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2316 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2318 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2319 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2320 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2321 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2322 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2323 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2324 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2325 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2326 break;
2327 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2328 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2329 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2330 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2331 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2332 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2333 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2334 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2335 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2336 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2337 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2338 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2339 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2340 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2341 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2342 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2343 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2344 switch (opr1) {
2345 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2346 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2347 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2348 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2350 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2351 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2352 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2353 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2354 break;
2355 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2356 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2357 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2358 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2359 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2360 switch (opr1) {
2361 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2362 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2363 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2364 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2366 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2367 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2368 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2369 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2370 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2371 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2372 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2373 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2374 switch (opr1) {
2375 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2376 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2378 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2379 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2380 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2381 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2382 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2383 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2384 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2385 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2386 break;
2387 case WINED3DTOP_MULTIPLYADD:
2388 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2389 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2390 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2391 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2392 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2393 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2394 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2395 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2396 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2397 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2398 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2399 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2400 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2401 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2402 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2403 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2404 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2405 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2406 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2407 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2408 break;
2410 case WINED3DTOP_BUMPENVMAP:
2414 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2415 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2417 default:
2418 Handled = FALSE;
2420 if (Handled) {
2421 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2422 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2424 return;
2426 } /* GL_NV_texture_env_combine4 */
2428 Handled = TRUE; /* Again, assume handled */
2429 switch (op) {
2430 case WINED3DTOP_DISABLE: /* Only for alpha */
2431 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2432 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2433 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2434 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2435 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2436 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2437 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2438 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2439 break;
2440 case WINED3DTOP_SELECTARG1:
2441 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2442 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2443 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2444 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2445 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2446 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2447 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2448 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2449 break;
2450 case WINED3DTOP_SELECTARG2:
2451 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2452 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2453 glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2454 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2455 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2456 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2457 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2458 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2459 break;
2460 case WINED3DTOP_MODULATE:
2461 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2462 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2463 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2464 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2465 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2466 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2467 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2468 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2469 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2470 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2471 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2472 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2473 break;
2474 case WINED3DTOP_MODULATE2X:
2475 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2476 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2477 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2478 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2479 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2480 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2481 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2482 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2483 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2484 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2485 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2486 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2487 break;
2488 case WINED3DTOP_MODULATE4X:
2489 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2490 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2491 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2492 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2493 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2494 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2495 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2496 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2497 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2498 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2499 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2500 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2501 break;
2502 case WINED3DTOP_ADD:
2503 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2504 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2505 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2506 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2507 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2508 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2509 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2510 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2511 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2512 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2513 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2514 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2515 break;
2516 case WINED3DTOP_ADDSIGNED:
2517 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2518 checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)");
2519 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2520 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2521 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2522 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2523 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2524 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2525 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2526 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2527 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2528 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2529 break;
2530 case WINED3DTOP_ADDSIGNED2X:
2531 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED));
2532 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)");
2533 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2534 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2535 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2536 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2537 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2538 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2539 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2540 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2541 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2542 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2543 break;
2544 case WINED3DTOP_SUBTRACT:
2545 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) {
2546 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2547 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)");
2548 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2549 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2550 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2551 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2552 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2553 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2554 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2555 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2556 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2557 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2558 } else {
2559 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2561 break;
2563 case WINED3DTOP_BLENDDIFFUSEALPHA:
2564 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2565 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2566 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2567 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2568 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2569 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2570 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2571 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2572 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2573 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2574 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR));
2575 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2576 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2577 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2578 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2579 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2580 break;
2581 case WINED3DTOP_BLENDTEXTUREALPHA:
2582 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2583 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2584 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2585 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2586 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2587 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2588 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2589 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2590 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2591 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2592 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2593 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2594 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2595 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2596 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2597 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2598 break;
2599 case WINED3DTOP_BLENDFACTORALPHA:
2600 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2601 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2602 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2603 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2604 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2605 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2606 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2607 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2608 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2609 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2610 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT));
2611 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2612 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2613 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2614 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2615 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2616 break;
2617 case WINED3DTOP_BLENDCURRENTALPHA:
2618 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2619 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2620 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2621 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2622 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2623 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2624 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2625 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2626 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2627 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2628 glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS));
2629 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2630 glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2631 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2632 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2633 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2634 break;
2635 case WINED3DTOP_DOTPRODUCT3:
2636 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) {
2637 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2638 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2639 } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) {
2640 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2641 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2642 } else {
2643 FIXME("This version of opengl does not support GL_DOT3\n");
2645 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2646 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2647 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2648 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2649 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2650 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2651 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2652 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2653 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2654 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2655 break;
2656 case WINED3DTOP_LERP:
2657 glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE));
2658 checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)");
2659 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2660 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2661 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2662 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2663 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2664 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2665 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2666 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2667 glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2668 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2669 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2670 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2671 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2672 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2673 break;
2674 case WINED3DTOP_ADDSMOOTH:
2675 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2676 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2677 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2678 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2679 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2680 switch (opr1) {
2681 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2682 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2683 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2684 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2686 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2687 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2688 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2689 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2690 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2691 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2692 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2693 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2694 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2695 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2696 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2697 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2698 } else
2699 Handled = FALSE;
2700 break;
2701 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2702 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2703 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2704 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2705 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2706 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2707 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2708 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2709 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2710 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2711 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2712 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2713 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2714 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2715 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2716 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2717 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2718 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2719 } else
2720 Handled = FALSE;
2721 break;
2722 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2723 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2724 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2725 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2726 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2727 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2728 switch (opr1) {
2729 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2730 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2731 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2732 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2734 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2735 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2736 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2737 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2738 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2739 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2740 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2741 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2742 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2743 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2744 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2745 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2746 } else
2747 Handled = FALSE;
2748 break;
2749 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2750 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2751 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2752 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2753 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2754 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2755 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2756 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2757 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2758 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2759 switch (opr1) {
2760 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2761 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2762 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2763 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2765 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2766 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2767 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2768 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2769 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2770 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2771 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2772 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2773 } else
2774 Handled = FALSE;
2775 break;
2776 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2777 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2778 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2779 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2780 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2781 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2782 switch (opr1) {
2783 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2784 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2785 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2786 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2788 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2789 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2790 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2791 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2792 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2793 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2794 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2795 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2796 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2797 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2798 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2799 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2800 } else
2801 Handled = FALSE;
2802 break;
2803 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2804 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2805 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2806 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2807 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2808 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2809 switch (opr1) {
2810 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2811 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2812 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2813 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2815 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2816 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2817 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2818 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2819 switch (opr1) {
2820 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2821 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2822 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2823 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2825 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2826 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2827 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2828 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2829 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2830 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2831 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2832 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2833 } else
2834 Handled = FALSE;
2835 break;
2836 case WINED3DTOP_MULTIPLYADD:
2837 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) {
2838 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2839 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2840 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2841 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2842 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2843 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2844 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
2845 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
2846 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
2847 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
2848 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2849 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2850 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2851 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2852 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2853 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2854 } else
2855 Handled = FALSE;
2856 break;
2857 case WINED3DTOP_BUMPENVMAPLUMINANCE:
2858 case WINED3DTOP_BUMPENVMAP:
2859 if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
2860 /* Technically texture shader support without register combiners is possible, but not expected to occur
2861 * on real world cards, so for now a fixme should be enough
2863 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
2865 default:
2866 Handled = FALSE;
2869 if (Handled) {
2870 BOOL combineOK = TRUE;
2871 if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
2872 DWORD op2;
2874 if (isAlpha) {
2875 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP];
2876 } else {
2877 op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP];
2880 /* Note: If COMBINE4 in effect can't go back to combine! */
2881 switch (op2) {
2882 case WINED3DTOP_ADDSMOOTH:
2883 case WINED3DTOP_BLENDTEXTUREALPHAPM:
2884 case WINED3DTOP_MODULATEALPHA_ADDCOLOR:
2885 case WINED3DTOP_MODULATECOLOR_ADDALPHA:
2886 case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR:
2887 case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA:
2888 case WINED3DTOP_MULTIPLYADD:
2889 /* Ignore those implemented in both cases */
2890 switch (op) {
2891 case WINED3DTOP_SELECTARG1:
2892 case WINED3DTOP_SELECTARG2:
2893 combineOK = FALSE;
2894 Handled = FALSE;
2895 break;
2896 default:
2897 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
2898 return;
2903 if (combineOK) {
2904 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE));
2905 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)");
2907 return;
2911 /* After all the extensions, if still unhandled, report fixme */
2912 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
2916 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2918 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2919 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
2920 BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
2922 TRACE("Setting color op for stage %d\n", stage);
2924 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
2925 if (use_ps(stateblock)) return;
2927 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
2929 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
2931 if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
2932 FIXME("Attempt to enable unsupported stage!\n");
2933 return;
2935 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2936 checkGLcall("glActiveTextureARB");
2939 if(stage >= stateblock->lowest_disabled_stage) {
2940 TRACE("Stage disabled\n");
2941 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
2943 /* Disable everything here */
2944 glDisable(GL_TEXTURE_2D);
2945 checkGLcall("glDisable(GL_TEXTURE_2D)");
2946 glDisable(GL_TEXTURE_3D);
2947 checkGLcall("glDisable(GL_TEXTURE_3D)");
2948 if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
2949 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
2950 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
2952 if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
2953 glDisable(GL_TEXTURE_RECTANGLE_ARB);
2954 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
2957 /* All done */
2958 return;
2961 /* The sampler will also activate the correct texture dimensions, so no need to do it here
2962 * if the sampler for this stage is dirty
2964 if(!isStateDirty(context, STATE_SAMPLER(stage))) {
2965 if (tex_used) texture_activate_dimensions(stage, stateblock, context);
2968 set_tex_op(context, (IWineD3DDevice *)stateblock->wineD3DDevice, FALSE, stage,
2969 stateblock->textureState[stage][WINED3DTSS_COLOROP],
2970 stateblock->textureState[stage][WINED3DTSS_COLORARG1],
2971 stateblock->textureState[stage][WINED3DTSS_COLORARG2],
2972 stateblock->textureState[stage][WINED3DTSS_COLORARG0]);
2975 void tex_alphaop(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
2977 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
2978 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
2979 BOOL tex_used = stateblock->wineD3DDevice->fixed_function_usage_map & (1 << stage);
2980 DWORD op, arg1, arg2, arg0;
2982 TRACE("Setting alpha op for stage %d\n", stage);
2983 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
2984 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
2986 if (tex_used && mapped_stage >= GL_LIMITS(textures)) {
2987 FIXME("Attempt to enable unsupported stage!\n");
2988 return;
2990 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
2991 checkGLcall("glActiveTextureARB");
2994 op = stateblock->textureState[stage][WINED3DTSS_ALPHAOP];
2995 arg1 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG1];
2996 arg2 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG2];
2997 arg0 = stateblock->textureState[stage][WINED3DTSS_ALPHAARG0];
2999 if (stateblock->renderState[WINED3DRS_COLORKEYENABLE] && stage == 0 && stateblock->textures[0])
3001 UINT texture_dimensions = IWineD3DBaseTexture_GetTextureDimensions(stateblock->textures[0]);
3003 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3005 IWineD3DSurfaceImpl *surf;
3007 surf = (IWineD3DSurfaceImpl *) ((IWineD3DTextureImpl *) stateblock->textures[0])->surfaces[0];
3009 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format_desc->alpha_mask)
3011 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3012 * properly. On the other hand applications can still use texture combiners apparently. This code
3013 * takes care that apps cannot remove the texture's alpha channel entirely.
3015 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3016 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3017 * and alpha component of diffuse color to draw things like translucent text and perform other
3018 * blending effects.
3020 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3021 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3022 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3023 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3024 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3025 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3026 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3027 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3028 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3029 * alpha.
3031 * What to do with multitexturing? So far no app has been found that uses color keying with
3032 * multitexturing */
3033 if (op == WINED3DTOP_DISABLE)
3035 arg1 = WINED3DTA_TEXTURE;
3036 op = WINED3DTOP_SELECTARG1;
3038 else if(op == WINED3DTOP_SELECTARG1 && arg1 != WINED3DTA_TEXTURE)
3040 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
3042 arg2 = WINED3DTA_TEXTURE;
3043 op = WINED3DTOP_MODULATE;
3045 else arg1 = WINED3DTA_TEXTURE;
3047 else if(op == WINED3DTOP_SELECTARG2 && arg2 != WINED3DTA_TEXTURE)
3049 if (stateblock->renderState[WINED3DRS_ALPHABLENDENABLE])
3051 arg1 = WINED3DTA_TEXTURE;
3052 op = WINED3DTOP_MODULATE;
3054 else arg2 = WINED3DTA_TEXTURE;
3060 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3061 * this if block here, and the other code(color keying, texture unit selection) are the same
3063 TRACE("Setting alpha op for stage %d\n", stage);
3064 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
3065 set_tex_op_nvrc((IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
3066 op, arg1, arg2, arg0,
3067 mapped_stage,
3068 stateblock->textureState[stage][WINED3DTSS_RESULTARG]);
3069 } else {
3070 set_tex_op(context, (IWineD3DDevice *)stateblock->wineD3DDevice, TRUE, stage,
3071 op, arg1, arg2, arg0);
3075 static void transform_texture(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3077 DWORD texUnit = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3078 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[texUnit];
3079 BOOL generated;
3080 int coordIdx;
3082 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3083 if (use_vs(stateblock) || isStateDirty(context, STATE_VDECL))
3085 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3086 return;
3089 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3091 if(mapped_stage >= GL_LIMITS(textures)) {
3092 return;
3094 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3095 checkGLcall("glActiveTextureARB");
3096 generated = (stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX] & 0xFFFF0000) != WINED3DTSS_TCI_PASSTHRU;
3097 coordIdx = min(stateblock->textureState[texUnit][WINED3DTSS_TEXCOORDINDEX & 0x0000FFFF], MAX_TEXTURES - 1);
3099 set_texture_matrix(&stateblock->transforms[WINED3DTS_TEXTURE0 + texUnit].u.m[0][0],
3100 stateblock->textureState[texUnit][WINED3DTSS_TEXTURETRANSFORMFLAGS], generated, context->last_was_rhw,
3101 stateblock->wineD3DDevice->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3102 ? stateblock->wineD3DDevice->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format_desc->format
3103 : WINED3DFMT_UNKNOWN,
3104 stateblock->wineD3DDevice->frag_pipe->ffp_proj_control);
3106 /* The sampler applying function calls us if this changes */
3107 if ((context->lastWasPow2Texture & (1 << texUnit)) && stateblock->textures[texUnit])
3109 if(generated) {
3110 FIXME("Non-power2 texture being used with generated texture coords\n");
3112 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3113 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3114 if (!use_ps(stateblock)) {
3115 TRACE("Non power two matrix multiply fixup\n");
3116 glMultMatrixf(((IWineD3DTextureImpl *) stateblock->textures[texUnit])->baseTexture.pow2Matrix);
3121 static void unloadTexCoords(const struct wined3d_context *context)
3123 unsigned int texture_idx;
3125 for (texture_idx = 0; texture_idx < GL_LIMITS(texture_stages); ++texture_idx) {
3126 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3127 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3131 static void loadTexCoords(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
3132 const struct wined3d_stream_info *si, GLuint *curVBO)
3134 const UINT *offset = stateblock->streamOffset;
3135 unsigned int mapped_stage = 0;
3136 unsigned int textureNo = 0;
3138 for (textureNo = 0; textureNo < GL_LIMITS(texture_stages); ++textureNo) {
3139 int coordIdx = stateblock->textureState[textureNo][WINED3DTSS_TEXCOORDINDEX];
3141 mapped_stage = stateblock->wineD3DDevice->texUnitMap[textureNo];
3142 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3144 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3146 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3148 TRACE("Setting up texture %u, idx %d, cordindx %u, data %p\n",
3149 textureNo, mapped_stage, coordIdx, e->data);
3151 if (*curVBO != e->buffer_object)
3153 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
3154 checkGLcall("glBindBufferARB");
3155 *curVBO = e->buffer_object;
3158 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3159 checkGLcall("glClientActiveTextureARB");
3161 /* The coords to supply depend completely on the fvf / vertex shader */
3162 glTexCoordPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
3163 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
3164 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3165 } else {
3166 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3169 if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
3170 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one */
3171 for (textureNo = mapped_stage + 1; textureNo < GL_LIMITS(textures); ++textureNo) {
3172 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3176 checkGLcall("loadTexCoords");
3179 static void tex_coordindex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3181 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3182 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
3183 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3184 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3185 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3186 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3188 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3190 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3191 return;
3194 if(mapped_stage >= GL_LIMITS(fragment_samplers)) {
3195 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3196 return;
3198 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3199 checkGLcall("glActiveTextureARB");
3201 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3203 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3204 * eg. SetTextureStageState( 0, WINED3DTSS_TEXCOORDINDEX, WINED3DTSS_TCI_CAMERASPACEPOSITION | 1 );
3205 * means use the vertex position (camera-space) as the input texture coordinates
3206 * for this texture stage, and the wrap mode set in the WINED3DRS_WRAP1 render
3207 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3208 * to the TEXCOORDINDEX value
3210 switch (stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX] & 0xffff0000)
3212 case WINED3DTSS_TCI_PASSTHRU:
3213 /* Use the specified texture coordinates contained within the
3214 * vertex format. This value resolves to zero. */
3215 glDisable(GL_TEXTURE_GEN_S);
3216 glDisable(GL_TEXTURE_GEN_T);
3217 glDisable(GL_TEXTURE_GEN_R);
3218 glDisable(GL_TEXTURE_GEN_Q);
3219 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3220 break;
3222 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3223 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3224 * as the input texture coordinates for this stage's texture transformation. This
3225 * equates roughly to EYE_LINEAR */
3227 glMatrixMode(GL_MODELVIEW);
3228 glPushMatrix();
3229 glLoadIdentity();
3230 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3231 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3232 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3233 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3234 glPopMatrix();
3235 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3237 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3238 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3239 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3240 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3242 glEnable(GL_TEXTURE_GEN_S);
3243 glEnable(GL_TEXTURE_GEN_T);
3244 glEnable(GL_TEXTURE_GEN_R);
3245 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3247 break;
3249 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3250 /* Note that NV_TEXGEN_REFLECTION support is implied when
3251 * ARB_TEXTURE_CUBE_MAP is supported */
3252 if (!GL_SUPPORT(NV_TEXGEN_REFLECTION))
3254 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3255 break;
3258 glMatrixMode(GL_MODELVIEW);
3259 glPushMatrix();
3260 glLoadIdentity();
3261 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3262 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3263 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3264 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3265 glPopMatrix();
3266 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3268 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3269 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3270 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3271 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3273 glEnable(GL_TEXTURE_GEN_S);
3274 glEnable(GL_TEXTURE_GEN_T);
3275 glEnable(GL_TEXTURE_GEN_R);
3276 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3278 break;
3280 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3281 /* Note that NV_TEXGEN_REFLECTION support is implied when
3282 * ARB_TEXTURE_CUBE_MAP is supported */
3283 if (!GL_SUPPORT(NV_TEXGEN_REFLECTION))
3285 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3286 break;
3289 glMatrixMode(GL_MODELVIEW);
3290 glPushMatrix();
3291 glLoadIdentity();
3292 glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3293 glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3294 glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3295 glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3296 glPopMatrix();
3297 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3299 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3300 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3301 glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3302 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3304 glEnable(GL_TEXTURE_GEN_S);
3305 glEnable(GL_TEXTURE_GEN_T);
3306 glEnable(GL_TEXTURE_GEN_R);
3307 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3309 break;
3311 case WINED3DTSS_TCI_SPHEREMAP:
3312 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3313 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3314 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3316 glEnable(GL_TEXTURE_GEN_S);
3317 glEnable(GL_TEXTURE_GEN_T);
3318 glDisable(GL_TEXTURE_GEN_R);
3319 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3321 break;
3323 default:
3324 FIXME("Unhandled WINED3DTSS_TEXCOORDINDEX %#x\n",
3325 stateblock->textureState[stage][WINED3DTSS_TEXCOORDINDEX]);
3326 glDisable(GL_TEXTURE_GEN_S);
3327 glDisable(GL_TEXTURE_GEN_T);
3328 glDisable(GL_TEXTURE_GEN_R);
3329 glDisable(GL_TEXTURE_GEN_Q);
3330 checkGLcall("Disable texgen.");
3332 break;
3335 /* Update the texture matrix */
3336 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + stage))) {
3337 transform_texture(STATE_TEXTURESTAGE(stage, WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
3340 if(!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded) {
3341 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3342 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3343 * and do all the things linked to it
3344 * TODO: Tidy that up to reload only the arrays of the changed unit
3346 GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
3348 unloadTexCoords(context);
3349 loadTexCoords(context, stateblock, &stateblock->wineD3DDevice->strided_streams, &curVBO);
3353 static void shaderconstant(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3355 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3357 /* Vertex and pixel shader states will call a shader upload, don't do anything as long one of them
3358 * has an update pending
3360 if(isStateDirty(context, STATE_VDECL) ||
3361 isStateDirty(context, STATE_PIXELSHADER)) {
3362 return;
3365 device->shader_backend->shader_load_constants(context, use_ps(stateblock), use_vs(stateblock));
3368 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3370 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3372 if (stateblock->pixelShader && stage != 0
3373 && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.luminanceparams & (1 << stage)))
3375 /* The pixel shader has to know the luminance scale. Do a constants update if it
3376 * isn't scheduled anyway
3378 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3379 !isStateDirty(context, STATE_PIXELSHADER)) {
3380 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3385 static void sampler_texmatrix(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3387 const DWORD sampler = state - STATE_SAMPLER(0);
3388 IWineD3DBaseTexture *texture = stateblock->textures[sampler];
3390 TRACE("state %#x, stateblock %p, context %p\n", state, stateblock, context);
3392 if(!texture) return;
3393 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3394 * basetexture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3395 * scaling is reapplied or removed, the texture matrix has to be reapplied
3397 * The mapped stage is already active because the sampler() function below, which is part of the
3398 * misc pipeline
3400 if(sampler < MAX_TEXTURES) {
3401 const BOOL texIsPow2 = !((IWineD3DBaseTextureImpl *)texture)->baseTexture.pow2Matrix_identity;
3403 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3405 if (texIsPow2) context->lastWasPow2Texture |= 1 << sampler;
3406 else context->lastWasPow2Texture &= ~(1 << sampler);
3407 transform_texture(STATE_TEXTURESTAGE(stateblock->wineD3DDevice->texUnitMap[sampler], WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
3412 static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3414 DWORD sampler = state - STATE_SAMPLER(0);
3415 DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[sampler];
3416 union {
3417 float f;
3418 DWORD d;
3419 } tmpvalue;
3421 TRACE("Sampler: %d\n", sampler);
3422 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3423 * only has to bind textures and set the per texture states
3426 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3428 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3429 return;
3432 if (mapped_stage >= GL_LIMITS(combined_samplers)) {
3433 return;
3435 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3436 checkGLcall("glActiveTextureARB");
3438 if(stateblock->textures[sampler]) {
3439 BOOL srgb = stateblock->samplerState[sampler][WINED3DSAMP_SRGBTEXTURE];
3440 IWineD3DBaseTextureImpl *tex_impl = (IWineD3DBaseTextureImpl *) stateblock->textures[sampler];
3441 tex_impl->baseTexture.internal_preload(stateblock->textures[sampler], srgb ? SRGB_SRGB : SRGB_RGB);
3442 IWineD3DBaseTexture_BindTexture(stateblock->textures[sampler], srgb);
3443 basetexture_apply_state_changes(stateblock->textures[sampler],
3444 stateblock->textureState[sampler], stateblock->samplerState[sampler]);
3446 if (GL_SUPPORT(EXT_TEXTURE_LOD_BIAS)) {
3447 tmpvalue.d = stateblock->samplerState[sampler][WINED3DSAMP_MIPMAPLODBIAS];
3448 glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3449 GL_TEXTURE_LOD_BIAS_EXT,
3450 tmpvalue.f);
3451 checkGLcall("glTexEnvi(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3454 if (!use_ps(stateblock) && sampler < stateblock->lowest_disabled_stage)
3456 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
3457 /* If color keying is enabled update the alpha test, it depends on the existence
3458 * of a color key in stage 0
3460 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3464 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3465 if (!tex_impl->baseTexture.pow2Matrix_identity) {
3466 IWineD3DDeviceImpl* d3ddevice = stateblock->wineD3DDevice;
3467 d3ddevice->shader_backend->shader_load_np2fixup_constants(
3468 (IWineD3DDevice*)d3ddevice, use_ps(stateblock), use_vs(stateblock));
3470 } else if(mapped_stage < GL_LIMITS(textures)) {
3471 if(sampler < stateblock->lowest_disabled_stage) {
3472 /* TODO: What should I do with pixel shaders here ??? */
3473 if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
3474 /* If color keying is enabled update the alpha test, it depends on the existence
3475 * of a color key in stage 0
3477 state_alpha(WINED3DRS_COLORKEYENABLE, stateblock, context);
3479 } /* Otherwise tex_colorop disables the stage */
3480 glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler]);
3481 checkGLcall("glBindTexture(GL_TEXTURE_2D, stateblock->wineD3DDevice->dummyTextureName[sampler])");
3485 void apply_pixelshader(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3487 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
3488 BOOL use_pshader = use_ps(stateblock);
3489 BOOL use_vshader = use_vs(stateblock);
3490 int i;
3492 if (use_pshader) {
3493 if(!context->last_was_pshader) {
3494 /* Former draw without a pixel shader, some samplers
3495 * may be disabled because of WINED3DTSS_COLOROP = WINED3DTOP_DISABLE
3496 * make sure to enable them
3498 for(i=0; i < MAX_FRAGMENT_SAMPLERS; i++) {
3499 if(!isStateDirty(context, STATE_SAMPLER(i))) {
3500 sampler(STATE_SAMPLER(i), stateblock, context);
3503 context->last_was_pshader = TRUE;
3504 } else {
3505 /* Otherwise all samplers were activated by the code above in earlier draws, or by sampler()
3506 * if a different texture was bound. I don't have to do anything.
3509 } else {
3510 /* Disabled the pixel shader - color ops weren't applied
3511 * while it was enabled, so re-apply them.
3513 for(i=0; i < MAX_TEXTURES; i++) {
3514 if(!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP))) {
3515 device->StateTable[STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP)].apply
3516 (STATE_TEXTURESTAGE(i, WINED3DTSS_COLOROP), stateblock, context);
3519 context->last_was_pshader = FALSE;
3522 if(!isStateDirty(context, device->StateTable[STATE_VSHADER].representative)) {
3523 device->shader_backend->shader_select(context, use_pshader, use_vshader);
3525 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader)) {
3526 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
3531 static void shader_bumpenvmat(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3533 DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3534 if (stateblock->pixelShader && stage != 0
3535 && (((IWineD3DPixelShaderImpl *)stateblock->pixelShader)->baseShader.reg_maps.bumpmat & (1 << stage)))
3537 /* The pixel shader has to know the bump env matrix. Do a constants update if it isn't scheduled
3538 * anyway
3540 if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&
3541 !isStateDirty(context, STATE_PIXELSHADER)) {
3542 shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, context);
3547 static void transform_world(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3549 /* This function is called by transform_view below if the view matrix was changed too
3551 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3552 * does not always update the world matrix, only on a switch between transformed
3553 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3554 * draw, but that should be rather rare and cheaper in total.
3556 glMatrixMode(GL_MODELVIEW);
3557 checkGLcall("glMatrixMode");
3559 if(context->last_was_rhw) {
3560 glLoadIdentity();
3561 checkGLcall("glLoadIdentity()");
3562 } else {
3563 /* In the general case, the view matrix is the identity matrix */
3564 if (stateblock->wineD3DDevice->view_ident) {
3565 glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3566 checkGLcall("glLoadMatrixf");
3567 } else {
3568 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3569 checkGLcall("glLoadMatrixf");
3570 glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(0)].u.m[0][0]);
3571 checkGLcall("glMultMatrixf");
3576 static void clipplane(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3578 UINT index = state - STATE_CLIPPLANE(0);
3580 if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW)) || index >= GL_LIMITS(clipplanes)) {
3581 return;
3584 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3585 if(!use_vs(stateblock)) {
3586 glMatrixMode(GL_MODELVIEW);
3587 glPushMatrix();
3588 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3589 } else {
3590 /* with vertex shaders, clip planes are not transformed in direct3d,
3591 * in OpenGL they are still transformed by the model view.
3592 * Use this to swap the y coordinate if necessary
3594 glMatrixMode(GL_MODELVIEW);
3595 glPushMatrix();
3596 glLoadIdentity();
3597 if (context->render_offscreen) glScalef(1.0f, -1.0f, 1.0f);
3600 TRACE("Clipplane [%f,%f,%f,%f]\n",
3601 stateblock->clipplane[index][0],
3602 stateblock->clipplane[index][1],
3603 stateblock->clipplane[index][2],
3604 stateblock->clipplane[index][3]);
3605 glClipPlane(GL_CLIP_PLANE0 + index, stateblock->clipplane[index]);
3606 checkGLcall("glClipPlane");
3608 glPopMatrix();
3611 static void transform_worldex(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3613 UINT matrix = state - STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0));
3614 GLenum glMat;
3615 TRACE("Setting world matrix %d\n", matrix);
3617 if(matrix >= GL_LIMITS(blends)) {
3618 WARN("Unsupported blend matrix set\n");
3619 return;
3620 } else if(isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
3621 return;
3624 /* GL_MODELVIEW0_ARB: 0x1700
3625 * GL_MODELVIEW1_ARB: 0x850a
3626 * GL_MODELVIEW2_ARB: 0x8722
3627 * GL_MODELVIEW3_ARB: 0x8723
3628 * etc
3629 * GL_MODELVIEW31_ARB: 0x873F
3631 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3632 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3634 glMatrixMode(glMat);
3635 checkGLcall("glMatrixMode(glMat)");
3637 /* World matrix 0 is multiplied with the view matrix because d3d uses 3 matrices while gl uses only 2. To avoid
3638 * weighting the view matrix incorrectly it has to be multiplied into every gl modelview matrix
3640 if(stateblock->wineD3DDevice->view_ident) {
3641 glLoadMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3642 checkGLcall("glLoadMatrixf");
3643 } else {
3644 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3645 checkGLcall("glLoadMatrixf");
3646 glMultMatrixf(&stateblock->transforms[WINED3DTS_WORLDMATRIX(matrix)].u.m[0][0]);
3647 checkGLcall("glMultMatrixf");
3651 static void state_vertexblend_w(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3653 static BOOL once = FALSE;
3655 switch(stateblock->renderState[WINED3DRS_VERTEXBLEND]) {
3656 case WINED3DVBF_1WEIGHTS:
3657 case WINED3DVBF_2WEIGHTS:
3658 case WINED3DVBF_3WEIGHTS:
3659 if(!once) {
3660 once = TRUE;
3661 /* TODO: Implement vertex blending in drawStridedSlow */
3662 FIXME("Vertex blending enabled, but not supported by hardware\n");
3664 break;
3666 case WINED3DVBF_TWEENING:
3667 WARN("Tweening not supported yet\n");
3671 static void state_vertexblend(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3673 WINED3DVERTEXBLENDFLAGS val = stateblock->renderState[WINED3DRS_VERTEXBLEND];
3675 switch(val) {
3676 case WINED3DVBF_1WEIGHTS:
3677 case WINED3DVBF_2WEIGHTS:
3678 case WINED3DVBF_3WEIGHTS:
3679 glEnable(GL_VERTEX_BLEND_ARB);
3680 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3682 /* D3D adds one more matrix which has weight (1 - sum(weights)). This is enabled at context
3683 * creation with enabling GL_WEIGHT_SUM_UNITY_ARB.
3685 GL_EXTCALL(glVertexBlendARB(stateblock->renderState[WINED3DRS_VERTEXBLEND] + 1));
3687 if(!stateblock->wineD3DDevice->vertexBlendUsed) {
3688 unsigned int i;
3689 for(i = 1; i < GL_LIMITS(blends); i++) {
3690 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)))) {
3691 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(i)), stateblock, context);
3694 stateblock->wineD3DDevice->vertexBlendUsed = TRUE;
3696 break;
3698 case WINED3DVBF_DISABLE:
3699 case WINED3DVBF_0WEIGHTS: /* for Indexed vertex blending - not supported */
3700 glDisable(GL_VERTEX_BLEND_ARB);
3701 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3702 break;
3704 case WINED3DVBF_TWEENING:
3705 /* Just set the vertex weight for weight 0, enable vertex blending and hope the app doesn't have
3706 * vertex weights in the vertices?
3707 * For now we don't report that as supported, so a warn should suffice
3709 WARN("Tweening not supported yet\n");
3710 break;
3714 static void transform_view(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3716 unsigned int k;
3718 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3719 * NOTE: We have to reset the positions even if the light/plane is not currently
3720 * enabled, since the call to enable it will not reset the position.
3721 * NOTE2: Apparently texture transforms do NOT need reapplying
3724 const PLIGHTINFOEL *light = NULL;
3726 glMatrixMode(GL_MODELVIEW);
3727 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3728 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
3729 checkGLcall("glLoadMatrixf(...)");
3731 /* Reset lights. TODO: Call light apply func */
3732 for(k = 0; k < stateblock->wineD3DDevice->maxConcurrentLights; k++) {
3733 light = stateblock->activeLights[k];
3734 if(!light) continue;
3735 glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3736 checkGLcall("glLightfv posn");
3737 glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3738 checkGLcall("glLightfv dirn");
3741 /* Reset Clipping Planes */
3742 for (k = 0; k < GL_LIMITS(clipplanes); k++) {
3743 if(!isStateDirty(context, STATE_CLIPPLANE(k))) {
3744 clipplane(STATE_CLIPPLANE(k), stateblock, context);
3748 if(context->last_was_rhw) {
3749 glLoadIdentity();
3750 checkGLcall("glLoadIdentity()");
3751 /* No need to update the world matrix, the identity is fine */
3752 return;
3755 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3756 * No need to do it here if the state is scheduled for update.
3758 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
3759 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
3762 /* Avoid looping over a number of matrices if the app never used the functionality */
3763 if(stateblock->wineD3DDevice->vertexBlendUsed) {
3764 for(k = 1; k < GL_LIMITS(blends); k++) {
3765 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)))) {
3766 transform_worldex(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(k)), stateblock, context);
3772 static void transform_projection(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3774 glMatrixMode(GL_PROJECTION);
3775 checkGLcall("glMatrixMode(GL_PROJECTION)");
3776 glLoadIdentity();
3777 checkGLcall("glLoadIdentity");
3779 if(context->last_was_rhw) {
3780 double X, Y, height, width, minZ, maxZ;
3782 X = stateblock->viewport.X;
3783 Y = stateblock->viewport.Y;
3784 height = stateblock->viewport.Height;
3785 width = stateblock->viewport.Width;
3786 minZ = stateblock->viewport.MinZ;
3787 maxZ = stateblock->viewport.MaxZ;
3789 if(!stateblock->wineD3DDevice->untransformed) {
3790 /* Transformed vertices are supposed to bypass the whole transform pipeline including
3791 * frustum clipping. This can't be done in opengl, so this code adjusts the Z range to
3792 * suppress depth clipping. This can be done because it is an orthogonal projection and
3793 * the Z coordinate does not affect the size of the primitives. Half Life 1 and Prince of
3794 * Persia 3D need this.
3796 * Note that using minZ and maxZ here doesn't entirely fix the problem, since view frustum
3797 * clipping is still enabled, but it seems to fix it for all apps tested so far. A minor
3798 * problem can be witnessed in half-life 1 engine based games, the weapon is clipped close
3799 * to the viewer.
3801 * Also note that this breaks z comparison against z values filled in with clear,
3802 * but no app depending on that and disabled clipping has been found yet. Comparing
3803 * primitives against themselves works, so the Z buffer is still intact for normal hidden
3804 * surface removal.
3806 * We could disable clipping entirely by setting the near to infinity and far to -infinity,
3807 * but this would break Z buffer operation. Raising the range to something less than
3808 * infinity would help a bit at the cost of Z precision, but it wouldn't eliminate the
3809 * problem either.
3811 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, -minZ, -maxZ);
3812 if (context->render_offscreen)
3814 glOrtho(X, X + width, -Y, -Y - height, -minZ, -maxZ);
3815 } else {
3816 glOrtho(X, X + width, Y + height, Y, -minZ, -maxZ);
3818 } else {
3819 /* If the app mixes transformed and untransformed primitives we can't use the coordinate system
3820 * trick above because this would mess up transformed and untransformed Z order. Pass the z position
3821 * unmodified to opengl.
3823 * If the app depends on mixed types and disabled clipping we're out of luck without a pipeline
3824 * replacement shader.
3826 TRACE("Calling glOrtho with %f, %f, %f, %f\n", width, height, 1.0, -1.0);
3827 if (context->render_offscreen)
3829 glOrtho(X, X + width, -Y, -Y - height, 0.0, -1.0);
3830 } else {
3831 glOrtho(X, X + width, Y + height, Y, 0.0, -1.0);
3834 checkGLcall("glOrtho");
3836 /* Window Coord 0 is the middle of the first pixel, so translate by 1/2 pixels */
3837 glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f);
3838 checkGLcall("glTranslatef(63.0f / 128.0f, 63.0f / 128.0f, 0.0f)");
3840 /* D3D texture coordinates are flipped compared to OpenGL ones, so
3841 * render everything upside down when rendering offscreen. */
3842 if (context->render_offscreen)
3844 glScalef(1.0f, -1.0f, 1.0f);
3845 checkGLcall("glScalef");
3847 } else {
3848 /* The rule is that the window coordinate 0 does not correspond to the
3849 beginning of the first pixel, but the center of the first pixel.
3850 As a consequence if you want to correctly draw one line exactly from
3851 the left to the right end of the viewport (with all matrices set to
3852 be identity), the x coords of both ends of the line would be not
3853 -1 and 1 respectively but (-1-1/viewport_widh) and (1-1/viewport_width)
3854 instead.
3856 1.0 / Width is used because the coord range goes from -1.0 to 1.0, then we
3857 divide by the Width/Height, so we need the half range(1.0) to translate by
3858 half a pixel.
3860 The other fun is that d3d's output z range after the transformation is [0;1],
3861 but opengl's is [-1;1]. Since the z buffer is in range [0;1] for both, gl
3862 scales [-1;1] to [0;1]. This would mean that we end up in [0.5;1] and loose a lot
3863 of Z buffer precision and the clear values do not match in the z test. Thus scale
3864 [0;1] to [-1;1], so when gl undoes that we utilize the full z range
3868 * Careful with the order of operations here, we're essentially working backwards:
3869 * x = x + 1/w;
3870 * y = (y - 1/h) * flip;
3871 * z = z * 2 - 1;
3873 * Becomes:
3874 * glTranslatef(0.0, 0.0, -1.0);
3875 * glScalef(1.0, 1.0, 2.0);
3877 * glScalef(1.0, flip, 1.0);
3878 * glTranslatef(1/w, -1/h, 0.0);
3880 * This is equivalent to:
3881 * glTranslatef(1/w, -flip/h, -1.0)
3882 * glScalef(1.0, flip, 2.0);
3885 /* Translate by slightly less than a half pixel to force a top-left
3886 * filling convention. We want the difference to be large enough that
3887 * it doesn't get lost due to rounding inside the driver, but small
3888 * enough to prevent it from interfering with any anti-aliasing. */
3889 GLfloat xoffset = (63.0f / 64.0f) / stateblock->viewport.Width;
3890 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height;
3892 if (context->render_offscreen)
3894 /* D3D texture coordinates are flipped compared to OpenGL ones, so
3895 * render everything upside down when rendering offscreen. */
3896 glTranslatef(xoffset, -yoffset, -1.0f);
3897 checkGLcall("glTranslatef(xoffset, -yoffset, -1.0f)");
3898 glScalef(1.0f, -1.0f, 2.0f);
3899 } else {
3900 glTranslatef(xoffset, yoffset, -1.0f);
3901 checkGLcall("glTranslatef(xoffset, yoffset, -1.0f)");
3902 glScalef(1.0f, 1.0f, 2.0f);
3904 checkGLcall("glScalef");
3906 glMultMatrixf(&stateblock->transforms[WINED3DTS_PROJECTION].u.m[0][0]);
3907 checkGLcall("glLoadMatrixf");
3911 /* This should match any arrays loaded in loadVertexData.
3912 * stateblock impl is required for GL_SUPPORT
3913 * TODO: Only load / unload arrays if we have to.
3915 static inline void unloadVertexData(const struct wined3d_context *context)
3917 glDisableClientState(GL_VERTEX_ARRAY);
3918 glDisableClientState(GL_NORMAL_ARRAY);
3919 glDisableClientState(GL_COLOR_ARRAY);
3920 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
3921 glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
3923 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
3924 glDisableClientState(GL_WEIGHT_ARRAY_ARB);
3926 unloadTexCoords(context);
3929 static inline void unload_numbered_array(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context, int i)
3931 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
3932 checkGLcall("glDisableVertexAttribArrayARB(reg)");
3934 context->numbered_array_mask &= ~(1 << i);
3937 /* This should match any arrays loaded in loadNumberedArrays
3938 * TODO: Only load / unload arrays if we have to.
3940 static inline void unloadNumberedArrays(IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
3942 /* disable any attribs (this is the same for both GLSL and ARB modes) */
3943 GLint maxAttribs = 16;
3944 int i;
3946 /* Leave all the attribs disabled */
3947 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &maxAttribs);
3948 /* MESA does not support it right not */
3949 if (glGetError() != GL_NO_ERROR)
3950 maxAttribs = 16;
3951 for (i = 0; i < maxAttribs; ++i) {
3952 unload_numbered_array(stateblock, context, i);
3956 static inline void loadNumberedArrays(IWineD3DStateBlockImpl *stateblock,
3957 const struct wined3d_stream_info *stream_info, struct wined3d_context *context)
3959 GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
3960 int i;
3961 const UINT *offset = stateblock->streamOffset;
3962 struct wined3d_buffer *vb;
3963 DWORD_PTR shift_index;
3965 /* Default to no instancing */
3966 stateblock->wineD3DDevice->instancedDraw = FALSE;
3968 for (i = 0; i < MAX_ATTRIBS; i++) {
3969 if (!(stream_info->use_map & (1 << i)))
3971 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
3972 continue;
3975 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
3976 if (stateblock->streamFlags[stream_info->elements[i].stream_idx] & WINED3DSTREAMSOURCE_INSTANCEDATA)
3978 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
3979 stateblock->wineD3DDevice->instancedDraw = TRUE;
3980 continue;
3983 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].buffer_object);
3985 if (stream_info->elements[i].stride)
3987 if (curVBO != stream_info->elements[i].buffer_object)
3989 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].buffer_object));
3990 checkGLcall("glBindBufferARB");
3991 curVBO = stream_info->elements[i].buffer_object;
3993 vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx];
3994 /* Use the VBO to find out if a vertex buffer exists, not the vb pointer. vb can point to a
3995 * user pointer data blob. In that case curVBO will be 0. If there is a vertex buffer but no
3996 * vbo we won't be load converted attributes anyway
3998 if (curVBO && vb->conversion_shift)
4000 TRACE("Loading attribute from shifted buffer\n");
4001 TRACE("Attrib %d has original stride %d, new stride %d\n",
4002 i, stream_info->elements[i].stride, vb->conversion_stride);
4003 TRACE("Original offset %p, additional offset 0x%08x\n",
4004 stream_info->elements[i].data, vb->conversion_shift[(DWORD_PTR)stream_info->elements[i].data]);
4005 TRACE("Opengl type %#x\n", stream_info->elements[i].format_desc->gl_vtx_type);
4006 shift_index = ((DWORD_PTR)stream_info->elements[i].data + offset[stream_info->elements[i].stream_idx]);
4007 shift_index = shift_index % stream_info->elements[i].stride;
4008 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format_desc->gl_vtx_format,
4009 stream_info->elements[i].format_desc->gl_vtx_type,
4010 stream_info->elements[i].format_desc->gl_normalized,
4011 vb->conversion_stride, stream_info->elements[i].data + vb->conversion_shift[shift_index]
4012 + stateblock->loadBaseVertexIndex * stream_info->elements[i].stride
4013 + offset[stream_info->elements[i].stream_idx]));
4015 } else {
4016 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format_desc->gl_vtx_format,
4017 stream_info->elements[i].format_desc->gl_vtx_type,
4018 stream_info->elements[i].format_desc->gl_normalized,
4019 stream_info->elements[i].stride, stream_info->elements[i].data
4020 + stateblock->loadBaseVertexIndex * stream_info->elements[i].stride
4021 + offset[stream_info->elements[i].stream_idx]));
4024 if (!(context->numbered_array_mask & (1 << i)))
4026 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4027 context->numbered_array_mask |= (1 << i);
4029 } else {
4030 /* Stride = 0 means always the same values. glVertexAttribPointerARB doesn't do that. Instead disable the pointer and
4031 * set up the attribute statically. But we have to figure out the system memory address.
4033 const BYTE *ptr = stream_info->elements[i].data + offset[stream_info->elements[i].stream_idx];
4034 if (stream_info->elements[i].buffer_object)
4036 vb = (struct wined3d_buffer *)stateblock->streamSource[stream_info->elements[i].stream_idx];
4037 ptr += (long) buffer_get_sysmem(vb);
4040 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(stateblock, context, i);
4042 switch (stream_info->elements[i].format_desc->format)
4044 case WINED3DFMT_R32_FLOAT:
4045 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4046 break;
4047 case WINED3DFMT_R32G32_FLOAT:
4048 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4049 break;
4050 case WINED3DFMT_R32G32B32_FLOAT:
4051 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4052 break;
4053 case WINED3DFMT_R32G32B32A32_FLOAT:
4054 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4055 break;
4057 case WINED3DFMT_R8G8B8A8_UINT:
4058 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4059 break;
4060 case WINED3DFMT_A8R8G8B8:
4061 if (GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA))
4063 const DWORD *src = (const DWORD *)ptr;
4064 DWORD c = *src & 0xff00ff00;
4065 c |= (*src & 0xff0000) >> 16;
4066 c |= (*src & 0xff) << 16;
4067 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4068 break;
4070 /* else fallthrough */
4071 case WINED3DFMT_R8G8B8A8_UNORM:
4072 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4073 break;
4075 case WINED3DFMT_R16G16_SINT:
4076 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4077 break;
4078 case WINED3DFMT_R16G16B16A16_SINT:
4079 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4080 break;
4082 case WINED3DFMT_R16G16_SNORM:
4084 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4085 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4086 break;
4088 case WINED3DFMT_R16G16_UNORM:
4090 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4091 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4092 break;
4094 case WINED3DFMT_R16G16B16A16_SNORM:
4095 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4096 break;
4097 case WINED3DFMT_R16G16B16A16_UNORM:
4098 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4099 break;
4101 case WINED3DFMT_R10G10B10A2_UINT:
4102 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4103 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4104 break;
4105 case WINED3DFMT_R10G10B10A2_SNORM:
4106 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4107 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4108 break;
4110 case WINED3DFMT_R16G16_FLOAT:
4111 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4112 * byte float according to the IEEE standard
4114 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4115 break;
4116 case WINED3DFMT_R16G16B16A16_FLOAT:
4117 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4118 break;
4120 default:
4121 ERR("Unexpected declaration in stride 0 attributes\n");
4122 break;
4127 checkGLcall("Loading numbered arrays");
4130 /* Used from 2 different functions, and too big to justify making it inlined */
4131 static void loadVertexData(const struct wined3d_context *context, IWineD3DStateBlockImpl *stateblock,
4132 const struct wined3d_stream_info *si)
4134 const UINT *offset = stateblock->streamOffset;
4135 GLuint curVBO = GL_SUPPORT(ARB_VERTEX_BUFFER_OBJECT) ? ~0U : 0;
4136 const struct wined3d_stream_info_element *e;
4138 TRACE("Using fast vertex array code\n");
4140 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4141 stateblock->wineD3DDevice->instancedDraw = FALSE;
4143 /* Blend Data ---------------------------------------------- */
4144 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4145 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4147 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4149 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
4150 TRACE("Blend %d %p %d\n", e->format_desc->component_count,
4151 e->data + stateblock->loadBaseVertexIndex * e->stride, e->stride + offset[e->stream_idx]);
4153 glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4154 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4156 GL_EXTCALL(glVertexBlendARB(e->format_desc->component_count + 1));
4158 VTRACE(("glWeightPointerARB(%d, GL_FLOAT, %d, %p)\n",
4159 WINED3D_ATR_FORMAT(sd->u.s.blendWeights.dwType) ,
4160 sd->u.s.blendWeights.dwStride,
4161 sd->u.s.blendWeights.lpData + stateblock->loadBaseVertexIndex * sd->u.s.blendWeights.dwStride + offset[sd->u.s.blendWeights.streamNo]));
4163 if (curVBO != e->buffer_object)
4165 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4166 checkGLcall("glBindBufferARB");
4167 curVBO = e->buffer_object;
4170 GL_EXTCALL(glWeightPointerARB)(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
4171 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4173 checkGLcall("glWeightPointerARB");
4175 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4177 static BOOL warned;
4178 if (!warned)
4180 FIXME("blendMatrixIndices support\n");
4181 warned = TRUE;
4184 } else {
4185 /* TODO: support blends in drawStridedSlow
4186 * No need to write a FIXME here, this is done after the general vertex decl decoding
4188 WARN("unsupported blending in openGl\n");
4190 } else {
4191 if (GL_SUPPORT(ARB_VERTEX_BLEND)) {
4192 static const GLbyte one = 1;
4193 GL_EXTCALL(glWeightbvARB(1, &one));
4194 checkGLcall("glWeightivARB(GL_LIMITS(blends), weights)");
4198 /* Point Size ----------------------------------------------*/
4199 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4201 /* no such functionality in the fixed function GL pipeline */
4202 TRACE("Cannot change ptSize here in openGl\n");
4203 /* TODO: Implement this function in using shaders if they are available */
4206 /* Vertex Pointers -----------------------------------------*/
4207 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4209 VTRACE(("glVertexPointer(%d, GL_FLOAT, %d, %p)\n", e->stride, e->size, e->data));
4211 e = &si->elements[WINED3D_FFP_POSITION];
4212 if (curVBO != e->buffer_object)
4214 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4215 checkGLcall("glBindBufferARB");
4216 curVBO = e->buffer_object;
4219 /* min(WINED3D_ATR_FORMAT(position),3) to Disable RHW mode as 'w' coord
4220 handling for rhw mode should not impact screen position whereas in GL it does.
4221 This may result in very slightly distorted textures in rhw mode.
4222 There's always the other option of fixing the view matrix to
4223 prevent w from having any effect.
4225 This only applies to user pointer sources, in VBOs the vertices are fixed up
4227 if (!e->buffer_object)
4229 glVertexPointer(3 /* min(e->format_desc->gl_vtx_format, 3) */, e->format_desc->gl_vtx_type, e->stride,
4230 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4231 } else {
4232 glVertexPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
4233 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4235 checkGLcall("glVertexPointer(...)");
4236 glEnableClientState(GL_VERTEX_ARRAY);
4237 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4240 /* Normals -------------------------------------------------*/
4241 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4243 VTRACE(("glNormalPointer(GL_FLOAT, %d, %p)\n", e->stride, e->data));
4245 e = &si->elements[WINED3D_FFP_NORMAL];
4246 if (curVBO != e->buffer_object)
4248 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4249 checkGLcall("glBindBufferARB");
4250 curVBO = e->buffer_object;
4252 glNormalPointer(e->format_desc->gl_vtx_type, e->stride,
4253 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4254 checkGLcall("glNormalPointer(...)");
4255 glEnableClientState(GL_NORMAL_ARRAY);
4256 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4258 } else {
4259 glNormal3f(0, 0, 0);
4260 checkGLcall("glNormal3f(0, 0, 0)");
4263 /* Diffuse Colour --------------------------------------------*/
4264 /* WARNING: Data here MUST be in RGBA format, so cannot */
4265 /* go directly into fast mode from app pgm, because */
4266 /* directx requires data in BGRA format. */
4267 /* currently fixupVertices swizzles the format, but this isn't*/
4268 /* very practical when using VBOs */
4269 /* NOTE: Unless we write a vertex shader to swizzle the colour*/
4270 /* , or the user doesn't care and wants the speed advantage */
4272 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4274 VTRACE(("glColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data));
4276 e = &si->elements[WINED3D_FFP_DIFFUSE];
4277 if (curVBO != e->buffer_object)
4279 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4280 checkGLcall("glBindBufferARB");
4281 curVBO = e->buffer_object;
4284 glColorPointer(e->format_desc->gl_vtx_format, e->format_desc->gl_vtx_type, e->stride,
4285 e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4286 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4287 glEnableClientState(GL_COLOR_ARRAY);
4288 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4290 } else {
4291 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4292 checkGLcall("glColor4f(1, 1, 1, 1)");
4295 /* Specular Colour ------------------------------------------*/
4296 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4298 TRACE("setting specular colour\n");
4299 VTRACE(("glSecondaryColorPointer(4, GL_UNSIGNED_BYTE, %d, %p)\n", e->stride, e->data));
4301 e = &si->elements[WINED3D_FFP_SPECULAR];
4302 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
4303 GLenum type = e->format_desc->gl_vtx_type;
4304 GLint format = e->format_desc->gl_vtx_format;
4306 if (curVBO != e->buffer_object)
4308 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->buffer_object));
4309 checkGLcall("glBindBufferARB");
4310 curVBO = e->buffer_object;
4313 if(format != 4 || (GLINFO_LOCATION.quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4315 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4316 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4317 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4318 * 4 component secondary colors use it
4320 GL_EXTCALL(glSecondaryColorPointerEXT)(format, type,
4321 e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4322 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4324 else
4326 switch(type)
4328 case GL_UNSIGNED_BYTE:
4329 GL_EXTCALL(glSecondaryColorPointerEXT)(3, GL_UNSIGNED_BYTE,
4330 e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4331 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4332 break;
4334 default:
4335 FIXME("Add 4 component specular color pointers for type %x\n", type);
4336 /* Make sure that the right color component is dropped */
4337 GL_EXTCALL(glSecondaryColorPointerEXT)(3, type,
4338 e->stride, e->data + stateblock->loadBaseVertexIndex * e->stride + offset[e->stream_idx]);
4339 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4342 glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4343 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4344 } else {
4346 /* Missing specular color is not critical, no warnings */
4347 VTRACE(("Specular colour is not supported in this GL implementation\n"));
4350 } else {
4351 if (GL_SUPPORT(EXT_SECONDARY_COLOR)) {
4352 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4353 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4354 } else {
4356 /* Missing specular color is not critical, no warnings */
4357 VTRACE(("Specular colour is not supported in this GL implementation\n"));
4361 /* Texture coords -------------------------------------------*/
4362 loadTexCoords(context, stateblock, si, &curVBO);
4365 static inline void drawPrimitiveTraceDataLocations(const struct wined3d_stream_info *dataLocations)
4367 /* Dump out what parts we have supplied */
4368 TRACE("Strided Data:\n");
4369 TRACE_STRIDED((dataLocations), WINED3D_FFP_POSITION);
4370 TRACE_STRIDED((dataLocations), WINED3D_FFP_BLENDWEIGHT);
4371 TRACE_STRIDED((dataLocations), WINED3D_FFP_BLENDINDICES);
4372 TRACE_STRIDED((dataLocations), WINED3D_FFP_NORMAL);
4373 TRACE_STRIDED((dataLocations), WINED3D_FFP_PSIZE);
4374 TRACE_STRIDED((dataLocations), WINED3D_FFP_DIFFUSE);
4375 TRACE_STRIDED((dataLocations), WINED3D_FFP_SPECULAR);
4376 TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD0);
4377 TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD1);
4378 TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD2);
4379 TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD3);
4380 TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD4);
4381 TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD5);
4382 TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD6);
4383 TRACE_STRIDED((dataLocations), WINED3D_FFP_TEXCOORD7);
4385 return;
4388 static void streamsrc(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4390 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
4391 BOOL fixup = FALSE;
4392 struct wined3d_stream_info *dataLocations = &device->strided_streams;
4393 BOOL useVertexShaderFunction;
4394 BOOL load_numbered = FALSE;
4395 BOOL load_named = FALSE;
4397 useVertexShaderFunction = (device->vs_selected_mode != SHADER_NONE && stateblock->vertexShader) ? TRUE : FALSE;
4399 if(device->up_strided) {
4400 /* Note: this is a ddraw fixed-function code path */
4401 TRACE("================ Strided Input ===================\n");
4402 device_stream_info_from_strided(device, device->up_strided, dataLocations);
4404 if(TRACE_ON(d3d)) {
4405 drawPrimitiveTraceDataLocations(dataLocations);
4407 } else {
4408 /* Note: This is a fixed function or shader codepath.
4409 * This means it must handle both types of strided data.
4410 * Shaders must go through here to zero the strided data, even if they
4411 * don't set any declaration at all
4413 TRACE("================ Vertex Declaration ===================\n");
4414 device_stream_info_from_declaration(device, useVertexShaderFunction, dataLocations, &fixup);
4417 if (dataLocations->position_transformed) useVertexShaderFunction = FALSE;
4419 if(useVertexShaderFunction) {
4420 if(((IWineD3DVertexDeclarationImpl *) stateblock->vertexDecl)->half_float_conv_needed && !fixup) {
4421 TRACE("Using drawStridedSlow with vertex shaders for FLOAT16 conversion\n");
4422 device->useDrawStridedSlow = TRUE;
4423 } else {
4424 load_numbered = TRUE;
4425 device->useDrawStridedSlow = FALSE;
4428 else
4430 WORD slow_mask = (1 << WINED3D_FFP_PSIZE);
4431 slow_mask |= -!GL_SUPPORT(EXT_VERTEX_ARRAY_BGRA) & ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
4433 if (fixup || (!dataLocations->position_transformed
4434 && !(dataLocations->use_map & slow_mask)))
4436 /* Load the vertex data using named arrays */
4437 load_named = TRUE;
4438 device->useDrawStridedSlow = FALSE;
4440 else
4442 TRACE("Not loading vertex data\n");
4443 device->useDrawStridedSlow = TRUE;
4447 if (context->numberedArraysLoaded && !load_numbered)
4449 unloadNumberedArrays(stateblock, context);
4450 context->numberedArraysLoaded = FALSE;
4451 context->numbered_array_mask = 0;
4453 else if (context->namedArraysLoaded)
4455 unloadVertexData(context);
4456 context->namedArraysLoaded = FALSE;
4459 if (load_numbered)
4461 TRACE("Loading numbered arrays\n");
4462 loadNumberedArrays(stateblock, dataLocations, context);
4463 context->numberedArraysLoaded = TRUE;
4465 else if (load_named)
4467 TRACE("Loading vertex data\n");
4468 loadVertexData(context, stateblock, dataLocations);
4469 context->namedArraysLoaded = TRUE;
4473 static void vertexdeclaration(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4475 BOOL updateFog = FALSE;
4476 BOOL useVertexShaderFunction = use_vs(stateblock);
4477 BOOL usePixelShaderFunction = use_ps(stateblock);
4478 BOOL transformed;
4479 /* Some stuff is in the device until we have per context tracking */
4480 IWineD3DDeviceImpl *device = stateblock->wineD3DDevice;
4481 BOOL wasrhw = context->last_was_rhw;
4482 unsigned int i;
4484 transformed = device->strided_streams.position_transformed;
4485 if(transformed != context->last_was_rhw && !useVertexShaderFunction) {
4486 updateFog = TRUE;
4489 /* Reapply lighting if it is not scheduled for reapplication already */
4490 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_LIGHTING))) {
4491 state_lighting(STATE_RENDER(WINED3DRS_LIGHTING), stateblock, context);
4494 if (transformed) {
4495 context->last_was_rhw = TRUE;
4496 } else {
4498 /* Untransformed, so relies on the view and projection matrices */
4499 context->last_was_rhw = FALSE;
4500 /* This turns off the Z scale trick to 'disable' viewport frustum clipping in rhw mode*/
4501 device->untransformed = TRUE;
4503 /* Todo for sw shaders: Vertex Shader output is already transformed, so set up identity matrices
4504 * Not needed as long as only hw shaders are supported
4507 /* This sets the shader output position correction constants.
4508 * TODO: Move to the viewport state
4510 if (useVertexShaderFunction)
4512 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height;
4513 device->posFixup[1] = context->render_offscreen ? -1.0f : 1.0f;
4514 device->posFixup[3] = device->posFixup[1] * yoffset;
4518 /* Don't have to apply the matrices when vertex shaders are used. When vshaders are turned
4519 * off this function will be called again anyway to make sure they're properly set
4521 if(!useVertexShaderFunction) {
4522 /* TODO: Move this mainly to the viewport state and only apply when the vp has changed
4523 * or transformed / untransformed was switched
4525 if(wasrhw != context->last_was_rhw &&
4526 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION)) &&
4527 !isStateDirty(context, STATE_VIEWPORT)) {
4528 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4530 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4531 * mode.
4533 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4534 * this check will fail and the matrix not applied again. This is OK because a simple
4535 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4536 * needs of the vertex declaration.
4538 * World and view matrix go into the same gl matrix, so only apply them when neither is
4539 * dirty
4541 if(transformed != wasrhw &&
4542 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0))) &&
4543 !isStateDirty(context, STATE_TRANSFORM(WINED3DTS_VIEW))) {
4544 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4547 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_COLORVERTEX))) {
4548 state_colormat(STATE_RENDER(WINED3DRS_COLORVERTEX), stateblock, context);
4551 if(context->last_was_vshader) {
4552 updateFog = TRUE;
4553 if(!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3DRS_CLIPPLANEENABLE))) {
4554 state_clipping(STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), stateblock, context);
4556 for(i = 0; i < GL_LIMITS(clipplanes); i++) {
4557 clipplane(STATE_CLIPPLANE(i), stateblock, context);
4560 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_NORMALIZENORMALS))) {
4561 state_normalize(STATE_RENDER(WINED3DRS_NORMALIZENORMALS), stateblock, context);
4563 } else {
4564 if(!context->last_was_vshader) {
4565 static BOOL warned = FALSE;
4566 if(!device->vs_clipping) {
4567 /* Disable all clip planes to get defined results on all drivers. See comment in the
4568 * state_clipping state handler
4570 for(i = 0; i < GL_LIMITS(clipplanes); i++) {
4571 glDisable(GL_CLIP_PLANE0 + i);
4572 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4575 if(!warned && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) {
4576 FIXME("Clipping not supported with vertex shaders\n");
4577 warned = TRUE;
4580 if(wasrhw) {
4581 /* Apply the transform matrices when switching from rhw drawing to vertex shaders. Vertex
4582 * shaders themselves do not need it, but the matrices are not reapplied automatically when
4583 * switching back from vertex shaders to fixed function processing. So make sure we leave the
4584 * fixed function vertex processing states back in a sane state before switching to shaders
4586 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4587 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4589 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)))) {
4590 transform_world(STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(0)), stateblock, context);
4593 updateFog = TRUE;
4595 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4596 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4597 * device->vs_clipping is false.
4599 for(i = 0; i < GL_LIMITS(clipplanes); i++) {
4600 clipplane(STATE_CLIPPLANE(i), stateblock, context);
4605 /* Vertex and pixel shaders are applied together for now, so let the last dirty state do the
4606 * application
4608 if (!isStateDirty(context, STATE_PIXELSHADER)) {
4609 device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4611 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (useVertexShaderFunction || usePixelShaderFunction)) {
4612 shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, context);
4616 context->last_was_vshader = useVertexShaderFunction;
4618 if(updateFog) {
4619 device->StateTable[STATE_RENDER(WINED3DRS_FOGVERTEXMODE)].apply(STATE_RENDER(WINED3DRS_FOGVERTEXMODE), stateblock, context);
4621 if(!useVertexShaderFunction) {
4622 int i;
4623 for(i = 0; i < MAX_TEXTURES; i++) {
4624 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_TEXTURE0 + i))) {
4625 transform_texture(STATE_TEXTURESTAGE(i, WINED3DTSS_TEXTURETRANSFORMFLAGS), stateblock, context);
4631 static void viewport_miscpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4633 UINT width, height;
4634 IWineD3DSurfaceImpl *target;
4636 glDepthRange(stateblock->viewport.MinZ, stateblock->viewport.MaxZ);
4637 checkGLcall("glDepthRange");
4638 /* Note: GL requires lower left, DirectX supplies upper left. This is reversed when using offscreen rendering
4640 if (context->render_offscreen)
4642 glViewport(stateblock->viewport.X,
4643 stateblock->viewport.Y,
4644 stateblock->viewport.Width, stateblock->viewport.Height);
4645 } else {
4646 target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
4647 target->get_drawable_size(context, &width, &height);
4649 glViewport(stateblock->viewport.X,
4650 (height - (stateblock->viewport.Y + stateblock->viewport.Height)),
4651 stateblock->viewport.Width, stateblock->viewport.Height);
4654 checkGLcall("glViewport");
4657 static void viewport_vertexpart(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4659 GLfloat yoffset = -(63.0f / 64.0f) / stateblock->viewport.Height;
4661 stateblock->wineD3DDevice->posFixup[2] = (63.0f / 64.0f) / stateblock->viewport.Width;
4662 stateblock->wineD3DDevice->posFixup[3] = stateblock->wineD3DDevice->posFixup[1] * yoffset;
4664 if(!isStateDirty(context, STATE_TRANSFORM(WINED3DTS_PROJECTION))) {
4665 transform_projection(STATE_TRANSFORM(WINED3DTS_PROJECTION), stateblock, context);
4667 if(!isStateDirty(context, STATE_RENDER(WINED3DRS_POINTSCALEENABLE))) {
4668 state_pscale(STATE_RENDER(WINED3DRS_POINTSCALEENABLE), stateblock, context);
4672 static void light(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4674 UINT Index = state - STATE_ACTIVELIGHT(0);
4675 const PLIGHTINFOEL *lightInfo = stateblock->activeLights[Index];
4677 if(!lightInfo) {
4678 glDisable(GL_LIGHT0 + Index);
4679 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4680 } else {
4681 float quad_att;
4682 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4684 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4685 glMatrixMode(GL_MODELVIEW);
4686 glPushMatrix();
4687 glLoadMatrixf(&stateblock->transforms[WINED3DTS_VIEW].u.m[0][0]);
4689 /* Diffuse: */
4690 colRGBA[0] = lightInfo->OriginalParms.Diffuse.r;
4691 colRGBA[1] = lightInfo->OriginalParms.Diffuse.g;
4692 colRGBA[2] = lightInfo->OriginalParms.Diffuse.b;
4693 colRGBA[3] = lightInfo->OriginalParms.Diffuse.a;
4694 glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4695 checkGLcall("glLightfv");
4697 /* Specular */
4698 colRGBA[0] = lightInfo->OriginalParms.Specular.r;
4699 colRGBA[1] = lightInfo->OriginalParms.Specular.g;
4700 colRGBA[2] = lightInfo->OriginalParms.Specular.b;
4701 colRGBA[3] = lightInfo->OriginalParms.Specular.a;
4702 glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4703 checkGLcall("glLightfv");
4705 /* Ambient */
4706 colRGBA[0] = lightInfo->OriginalParms.Ambient.r;
4707 colRGBA[1] = lightInfo->OriginalParms.Ambient.g;
4708 colRGBA[2] = lightInfo->OriginalParms.Ambient.b;
4709 colRGBA[3] = lightInfo->OriginalParms.Ambient.a;
4710 glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4711 checkGLcall("glLightfv");
4713 if ((lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range) >= FLT_MIN) {
4714 quad_att = 1.4f/(lightInfo->OriginalParms.Range *lightInfo->OriginalParms.Range);
4715 } else {
4716 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4719 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4720 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4721 * Attenuation0 to NaN and crashes in the gl lib
4724 switch (lightInfo->OriginalParms.Type) {
4725 case WINED3DLIGHT_POINT:
4726 /* Position */
4727 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4728 checkGLcall("glLightfv");
4729 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4730 checkGLcall("glLightf");
4731 /* Attenuation - Are these right? guessing... */
4732 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
4733 checkGLcall("glLightf");
4734 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
4735 checkGLcall("glLightf");
4736 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4737 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4738 checkGLcall("glLightf");
4739 /* FIXME: Range */
4740 break;
4742 case WINED3DLIGHT_SPOT:
4743 /* Position */
4744 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4745 checkGLcall("glLightfv");
4746 /* Direction */
4747 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4748 checkGLcall("glLightfv");
4749 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4750 checkGLcall("glLightf");
4751 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4752 checkGLcall("glLightf");
4753 /* Attenuation - Are these right? guessing... */
4754 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.Attenuation0);
4755 checkGLcall("glLightf");
4756 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.Attenuation1);
4757 checkGLcall("glLightf");
4758 if (quad_att < lightInfo->OriginalParms.Attenuation2) quad_att = lightInfo->OriginalParms.Attenuation2;
4759 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4760 checkGLcall("glLightf");
4761 /* FIXME: Range */
4762 break;
4764 case WINED3DLIGHT_DIRECTIONAL:
4765 /* Direction */
4766 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
4767 checkGLcall("glLightfv");
4768 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4769 checkGLcall("glLightf");
4770 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4771 checkGLcall("glLightf");
4772 break;
4774 default:
4775 FIXME("Unrecognized light type %d\n", lightInfo->OriginalParms.Type);
4778 /* Restore the modelview matrix */
4779 glPopMatrix();
4781 glEnable(GL_LIGHT0 + Index);
4782 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4785 return;
4788 static void scissorrect(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4790 RECT *pRect = &stateblock->scissorRect;
4791 UINT height;
4792 UINT width;
4793 IWineD3DSurfaceImpl *target = (IWineD3DSurfaceImpl *) stateblock->wineD3DDevice->render_targets[0];
4795 target->get_drawable_size(context, &width, &height);
4796 /* Warning: glScissor uses window coordinates, not viewport coordinates, so our viewport correction does not apply
4797 * Warning2: Even in windowed mode the coords are relative to the window, not the screen
4799 TRACE("(%p) Setting new Scissor Rect to %d:%d-%d:%d\n", stateblock->wineD3DDevice, pRect->left, pRect->bottom - height,
4800 pRect->right - pRect->left, pRect->bottom - pRect->top);
4802 if (context->render_offscreen)
4804 glScissor(pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top);
4805 } else {
4806 glScissor(pRect->left, height - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top);
4808 checkGLcall("glScissor");
4811 static void indexbuffer(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4813 if(stateblock->streamIsUP || stateblock->pIndexData == NULL ) {
4814 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4815 } else {
4816 struct wined3d_buffer *ib = (struct wined3d_buffer *) stateblock->pIndexData;
4817 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4821 static void frontface(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
4823 if (context->render_offscreen)
4825 glFrontFace(GL_CCW);
4826 checkGLcall("glFrontFace(GL_CCW)");
4827 } else {
4828 glFrontFace(GL_CW);
4829 checkGLcall("glFrontFace(GL_CW)");
4833 const struct StateEntryTemplate misc_state_template[] = {
4834 { STATE_RENDER(WINED3DRS_SRCBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4835 { STATE_RENDER(WINED3DRS_DESTBLEND), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4836 { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4837 { STATE_RENDER(WINED3DRS_EDGEANTIALIAS), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4838 { STATE_RENDER(WINED3DRS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4839 { STATE_RENDER(WINED3DRS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4840 { STATE_RENDER(WINED3DRS_SRCBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4841 { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4842 { STATE_RENDER(WINED3DRS_DESTBLENDALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4843 { STATE_RENDER(WINED3DRS_BLENDOPALPHA), { STATE_RENDER(WINED3DRS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4844 { STATE_STREAMSRC, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE },
4845 { STATE_VDECL, { STATE_VDECL, streamsrc }, WINED3D_GL_EXT_NONE },
4846 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4847 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4848 /* TODO: Move shader constant loading to vertex and fragment pipeline repectively, as soon as the pshader and
4849 * vshader loadings are untied from each other
4851 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4852 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4853 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4854 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4855 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4856 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4857 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4858 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4859 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4860 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4861 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4862 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4863 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4864 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4865 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4866 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4867 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4868 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4869 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4870 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4871 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4872 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4873 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4874 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4875 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4876 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4877 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4878 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4879 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4880 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4881 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4882 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT01), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4883 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT10), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4884 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT11), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVMAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4885 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4886 { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4887 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4888 { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(1, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4889 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4890 { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(2, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4891 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4892 { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(3, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4893 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4894 { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(4, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4895 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4896 { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(5, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4897 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4898 { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(6, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4899 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4900 { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLOFFSET), { STATE_TEXTURESTAGE(7, WINED3DTSS_BUMPENVLSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
4902 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
4903 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
4904 { STATE_RENDER(WINED3DRS_ANTIALIAS), { STATE_RENDER(WINED3DRS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
4905 { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3DRS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
4906 { STATE_RENDER(WINED3DRS_ZENABLE), { STATE_RENDER(WINED3DRS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
4907 { STATE_RENDER(WINED3DRS_WRAPU), { STATE_RENDER(WINED3DRS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
4908 { STATE_RENDER(WINED3DRS_WRAPV), { STATE_RENDER(WINED3DRS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
4909 { STATE_RENDER(WINED3DRS_FILLMODE), { STATE_RENDER(WINED3DRS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
4910 { STATE_RENDER(WINED3DRS_SHADEMODE), { STATE_RENDER(WINED3DRS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
4911 { STATE_RENDER(WINED3DRS_LINEPATTERN), { STATE_RENDER(WINED3DRS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
4912 { STATE_RENDER(WINED3DRS_MONOENABLE), { STATE_RENDER(WINED3DRS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
4913 { STATE_RENDER(WINED3DRS_ROP2), { STATE_RENDER(WINED3DRS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
4914 { STATE_RENDER(WINED3DRS_PLANEMASK), { STATE_RENDER(WINED3DRS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
4915 { STATE_RENDER(WINED3DRS_ZWRITEENABLE), { STATE_RENDER(WINED3DRS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
4916 { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
4917 { STATE_RENDER(WINED3DRS_ALPHAREF), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
4918 { STATE_RENDER(WINED3DRS_ALPHAFUNC), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
4919 { STATE_RENDER(WINED3DRS_COLORKEYENABLE), { STATE_RENDER(WINED3DRS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
4920 { STATE_RENDER(WINED3DRS_LASTPIXEL), { STATE_RENDER(WINED3DRS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
4921 { STATE_RENDER(WINED3DRS_CULLMODE), { STATE_RENDER(WINED3DRS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
4922 { STATE_RENDER(WINED3DRS_ZFUNC), { STATE_RENDER(WINED3DRS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
4923 { STATE_RENDER(WINED3DRS_DITHERENABLE), { STATE_RENDER(WINED3DRS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
4924 { STATE_RENDER(WINED3DRS_SUBPIXEL), { STATE_RENDER(WINED3DRS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
4925 { STATE_RENDER(WINED3DRS_SUBPIXELX), { STATE_RENDER(WINED3DRS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
4926 { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), { STATE_RENDER(WINED3DRS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
4927 { STATE_RENDER(WINED3DRS_ZBIAS), { STATE_RENDER(WINED3DRS_ZBIAS), state_zbias }, WINED3D_GL_EXT_NONE },
4928 { STATE_RENDER(WINED3DRS_STIPPLEENABLE), { STATE_RENDER(WINED3DRS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
4929 { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), { STATE_RENDER(WINED3DRS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
4930 { STATE_RENDER(WINED3DRS_ANISOTROPY), { STATE_RENDER(WINED3DRS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
4931 { STATE_RENDER(WINED3DRS_FLUSHBATCH), { STATE_RENDER(WINED3DRS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
4932 { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), { STATE_RENDER(WINED3DRS_TRANSLUCENTSORTINDEPENDENT), state_translucentsi }, WINED3D_GL_EXT_NONE },
4933 { STATE_RENDER(WINED3DRS_STENCILENABLE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4934 { STATE_RENDER(WINED3DRS_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4935 { STATE_RENDER(WINED3DRS_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4936 { STATE_RENDER(WINED3DRS_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4937 { STATE_RENDER(WINED3DRS_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4938 { STATE_RENDER(WINED3DRS_STENCILREF), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4939 { STATE_RENDER(WINED3DRS_STENCILMASK), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4940 { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
4941 { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), { STATE_RENDER(WINED3DRS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
4942 { STATE_RENDER(WINED3DRS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4943 { STATE_RENDER(WINED3DRS_CCW_STENCILFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4944 { STATE_RENDER(WINED3DRS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4945 { STATE_RENDER(WINED3DRS_CCW_STENCILPASS), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4946 { STATE_RENDER(WINED3DRS_CCW_STENCILFUNC), { STATE_RENDER(WINED3DRS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
4947 { STATE_RENDER(WINED3DRS_WRAP0), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4948 { STATE_RENDER(WINED3DRS_WRAP1), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4949 { STATE_RENDER(WINED3DRS_WRAP2), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4950 { STATE_RENDER(WINED3DRS_WRAP3), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4951 { STATE_RENDER(WINED3DRS_WRAP4), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4952 { STATE_RENDER(WINED3DRS_WRAP5), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4953 { STATE_RENDER(WINED3DRS_WRAP6), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4954 { STATE_RENDER(WINED3DRS_WRAP7), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4955 { STATE_RENDER(WINED3DRS_WRAP8), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4956 { STATE_RENDER(WINED3DRS_WRAP9), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4957 { STATE_RENDER(WINED3DRS_WRAP10), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4958 { STATE_RENDER(WINED3DRS_WRAP11), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4959 { STATE_RENDER(WINED3DRS_WRAP12), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4960 { STATE_RENDER(WINED3DRS_WRAP13), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4961 { STATE_RENDER(WINED3DRS_WRAP14), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4962 { STATE_RENDER(WINED3DRS_WRAP15), { STATE_RENDER(WINED3DRS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
4963 { STATE_RENDER(WINED3DRS_EXTENTS), { STATE_RENDER(WINED3DRS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
4964 { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3DRS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
4965 { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), { STATE_RENDER(WINED3DRS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
4966 { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), { STATE_RENDER(WINED3DRS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
4967 { STATE_RENDER(WINED3DRS_POSITIONDEGREE), { STATE_RENDER(WINED3DRS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
4968 { STATE_RENDER(WINED3DRS_NORMALDEGREE), { STATE_RENDER(WINED3DRS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
4969 { STATE_RENDER(WINED3DRS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
4970 { STATE_RENDER(WINED3DRS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
4971 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_X), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
4972 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
4973 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
4974 { STATE_RENDER(WINED3DRS_ADAPTIVETESS_W), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
4975 { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), { STATE_RENDER(WINED3DRS_ENABLEADAPTIVETESSELLATION), state_tessellation }, WINED3D_GL_EXT_NONE },
4976 { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
4977 { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3DRS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
4978 { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), { STATE_RENDER(WINED3DRS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
4979 { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3DRS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
4980 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
4981 { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
4982 { STATE_RENDER(WINED3DRS_BLENDOP), { STATE_RENDER(WINED3DRS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
4983 { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), { STATE_RENDER(WINED3DRS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
4984 { STATE_RENDER(WINED3DRS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
4985 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE1), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
4986 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE2), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
4987 { STATE_RENDER(WINED3DRS_COLORWRITEENABLE3), { STATE_RENDER(WINED3DRS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
4988 { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
4989 { STATE_RENDER(WINED3DRS_BLENDFACTOR), { STATE_RENDER(WINED3DRS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
4990 { STATE_RENDER(WINED3DRS_DEPTHBIAS), { STATE_RENDER(WINED3DRS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
4991 /* Samplers */
4992 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
4993 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
4994 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
4995 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
4996 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
4997 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
4998 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
4999 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5000 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5001 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5002 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5003 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5004 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5005 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5006 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5007 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5008 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5009 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5010 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5011 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5012 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5015 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5016 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5017 { STATE_VSHADER, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5018 { STATE_MATERIAL, { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5019 { STATE_RENDER(WINED3DRS_SPECULARENABLE), { STATE_RENDER(WINED3DRS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5020 /* Clip planes */
5021 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5022 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5023 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5024 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5025 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5026 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5027 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5028 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5029 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5030 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5031 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5032 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5033 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5034 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5035 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5036 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5037 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5038 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5039 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5040 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5041 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5042 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5043 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5044 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5045 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5046 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5047 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5048 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5049 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5050 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5051 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5052 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5053 /* Lights */
5054 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5055 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5056 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5057 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5058 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5059 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5060 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5061 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5062 /* Viewport */
5063 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5064 /* Transform states follow */
5065 { STATE_TRANSFORM(WINED3DTS_VIEW), { STATE_TRANSFORM(WINED3DTS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5066 { STATE_TRANSFORM(WINED3DTS_PROJECTION), { STATE_TRANSFORM(WINED3DTS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5067 { STATE_TRANSFORM(WINED3DTS_TEXTURE0), { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5068 { STATE_TRANSFORM(WINED3DTS_TEXTURE1), { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5069 { STATE_TRANSFORM(WINED3DTS_TEXTURE2), { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5070 { STATE_TRANSFORM(WINED3DTS_TEXTURE3), { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5071 { STATE_TRANSFORM(WINED3DTS_TEXTURE4), { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5072 { STATE_TRANSFORM(WINED3DTS_TEXTURE5), { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5073 { STATE_TRANSFORM(WINED3DTS_TEXTURE6), { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5074 { STATE_TRANSFORM(WINED3DTS_TEXTURE7), { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5075 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5076 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5077 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5078 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 3)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5079 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 4)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5080 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 5)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5081 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 6)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5082 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 7)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5083 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 8)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5084 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 9)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5085 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5086 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5087 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5088 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5089 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5090 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5091 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5092 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5093 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5094 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5095 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5096 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5097 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5098 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5099 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5100 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5101 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5102 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5103 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5104 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5105 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5106 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5107 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5108 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5109 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5110 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5111 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5112 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5113 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5114 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5115 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5116 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5117 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5118 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5119 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5120 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5121 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5122 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5123 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5124 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5125 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5126 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5127 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5128 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5129 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5130 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5131 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5132 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5133 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5134 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5135 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5136 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5137 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5138 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5139 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5140 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5141 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5142 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5143 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5144 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5145 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5146 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5147 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5148 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5149 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5150 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5151 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5152 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5153 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5154 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5155 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5156 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5157 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5158 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5159 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5160 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5161 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5162 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5163 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5164 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5165 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5166 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5167 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5168 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5169 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5170 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5171 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5172 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5173 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5174 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5175 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5176 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5177 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5178 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5179 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5180 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5181 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5182 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5183 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5184 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5185 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5186 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5187 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5188 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5189 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5190 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5191 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5192 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5193 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5194 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5195 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), { STATE_TRANSFORM(WINED3DTS_WORLDMATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(0,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5332 { STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(1,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5333 { STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(2,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5334 { STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(3,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5335 { STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(4,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5336 { STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(5,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5337 { STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(6,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5338 { STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),{STATE_TEXTURESTAGE(7,WINED3DTSS_TEXTURETRANSFORMFLAGS),transform_texture }, WINED3D_GL_EXT_NONE },
5339 { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(0, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(1, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(2, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(3, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(4, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(5, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(6, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), { STATE_TEXTURESTAGE(7, WINED3DTSS_TEXCOORDINDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5347 /* Fog */
5348 { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5349 { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5350 { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5351 { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog }, NV_FOG_DISTANCE },
5352 { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), { STATE_RENDER(WINED3DRS_RANGEFOGENABLE), state_rangefog_w }, WINED3D_GL_EXT_NONE },
5353 { STATE_RENDER(WINED3DRS_CLIPPING), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5354 { STATE_RENDER(WINED3DRS_CLIPPLANEENABLE), { STATE_RENDER(WINED3DRS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5355 { STATE_RENDER(WINED3DRS_LIGHTING), { STATE_RENDER(WINED3DRS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5356 { STATE_RENDER(WINED3DRS_AMBIENT), { STATE_RENDER(WINED3DRS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5357 { STATE_RENDER(WINED3DRS_COLORVERTEX), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5358 { STATE_RENDER(WINED3DRS_LOCALVIEWER), { STATE_RENDER(WINED3DRS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5359 { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), { STATE_RENDER(WINED3DRS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5360 { STATE_RENDER(WINED3DRS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5361 { STATE_RENDER(WINED3DRS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5362 { STATE_RENDER(WINED3DRS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5363 { STATE_RENDER(WINED3DRS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3DRS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5364 { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5365 { STATE_RENDER(WINED3DRS_VERTEXBLEND), { STATE_RENDER(WINED3DRS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5366 { STATE_RENDER(WINED3DRS_POINTSIZE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5367 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5368 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5369 { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5370 { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5371 { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), { STATE_RENDER(WINED3DRS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5372 { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5373 { STATE_RENDER(WINED3DRS_POINTSCALE_A), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5374 { STATE_RENDER(WINED3DRS_POINTSCALE_B), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5375 { STATE_RENDER(WINED3DRS_POINTSCALE_C), { STATE_RENDER(WINED3DRS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5376 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5377 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5378 { STATE_RENDER(WINED3DRS_POINTSIZE_MAX), { STATE_RENDER(WINED3DRS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5379 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5380 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5381 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5383 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5384 { STATE_SAMPLER(0), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5385 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5386 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5387 { STATE_SAMPLER(1), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5388 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5389 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5390 { STATE_SAMPLER(2), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5391 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5392 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5393 { STATE_SAMPLER(3), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5394 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5395 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5396 { STATE_SAMPLER(4), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5397 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5398 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5399 { STATE_SAMPLER(5), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5400 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5401 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5402 { STATE_SAMPLER(6), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5403 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5404 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5405 { STATE_SAMPLER(7), { 0, NULL }, WINE_NORMALIZED_TEXRECT },
5406 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5407 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5410 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5411 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5412 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5413 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5414 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5415 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5416 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5417 { STATE_TEXTURESTAGE(0, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5418 { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(0, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5419 { STATE_TEXTURESTAGE(0, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(0, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5420 { STATE_TEXTURESTAGE(0, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
5421 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5422 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5423 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5424 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5425 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5426 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5427 { STATE_TEXTURESTAGE(1, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5428 { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(1, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5429 { STATE_TEXTURESTAGE(1, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(1, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5430 { STATE_TEXTURESTAGE(1, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
5431 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5432 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5433 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5434 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5435 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5436 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5437 { STATE_TEXTURESTAGE(2, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5438 { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(2, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5439 { STATE_TEXTURESTAGE(2, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(2, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5440 { STATE_TEXTURESTAGE(2, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
5441 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5442 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5443 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5444 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5445 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5446 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5447 { STATE_TEXTURESTAGE(3, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5448 { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(3, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5449 { STATE_TEXTURESTAGE(3, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(3, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5450 { STATE_TEXTURESTAGE(3, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
5451 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5452 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5453 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5454 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5455 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5456 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5457 { STATE_TEXTURESTAGE(4, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5458 { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(4, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5459 { STATE_TEXTURESTAGE(4, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(4, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5460 { STATE_TEXTURESTAGE(4, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
5461 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5462 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5463 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5464 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5465 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5466 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5467 { STATE_TEXTURESTAGE(5, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5468 { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(5, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5469 { STATE_TEXTURESTAGE(5, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(5, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5470 { STATE_TEXTURESTAGE(5, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
5471 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5472 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5473 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5474 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5475 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5476 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5477 { STATE_TEXTURESTAGE(6, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5478 { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(6, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5479 { STATE_TEXTURESTAGE(6, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(6, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5480 { STATE_TEXTURESTAGE(6, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
5481 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5482 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5483 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5484 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5485 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG1), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5486 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG2), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5487 { STATE_TEXTURESTAGE(7, WINED3DTSS_COLORARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5488 { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAARG0), { STATE_TEXTURESTAGE(7, WINED3DTSS_ALPHAOP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5489 { STATE_TEXTURESTAGE(7, WINED3DTSS_RESULTARG), { STATE_TEXTURESTAGE(7, WINED3DTSS_COLOROP), tex_colorop }, WINED3D_GL_EXT_NONE },
5490 { STATE_TEXTURESTAGE(7, WINED3DTSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, state_nogl }, WINED3D_GL_EXT_NONE },
5491 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5492 { STATE_RENDER(WINED3DRS_SRGBWRITEENABLE), { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5493 { STATE_RENDER(WINED3DRS_BORDERCOLOR), { STATE_RENDER(WINED3DRS_BORDERCOLOR), state_bordercolor }, WINED3D_GL_EXT_NONE },
5494 { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), { STATE_RENDER(WINED3DRS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5495 { STATE_RENDER(WINED3DRS_FOGCOLOR), { STATE_RENDER(WINED3DRS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5496 { STATE_RENDER(WINED3DRS_FOGDENSITY), { STATE_RENDER(WINED3DRS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5497 { STATE_RENDER(WINED3DRS_FOGENABLE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5498 { STATE_RENDER(WINED3DRS_FOGTABLEMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5499 { STATE_RENDER(WINED3DRS_FOGVERTEXMODE), { STATE_RENDER(WINED3DRS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5500 { STATE_RENDER(WINED3DRS_FOGSTART), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5501 { STATE_RENDER(WINED3DRS_FOGEND), { STATE_RENDER(WINED3DRS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5502 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5503 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5504 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5505 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5506 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5507 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5508 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5509 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5510 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5512 #undef GLINFO_LOCATION
5514 #define GLINFO_LOCATION (*gl_info)
5515 /* Context activation is done by the caller. */
5516 static void ffp_enable(IWineD3DDevice *iface, BOOL enable) { }
5518 static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype,
5519 const struct wined3d_gl_info *gl_info, struct fragment_caps *pCaps)
5521 pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD |
5522 WINED3DTEXOPCAPS_ADDSIGNED |
5523 WINED3DTEXOPCAPS_ADDSIGNED2X |
5524 WINED3DTEXOPCAPS_MODULATE |
5525 WINED3DTEXOPCAPS_MODULATE2X |
5526 WINED3DTEXOPCAPS_MODULATE4X |
5527 WINED3DTEXOPCAPS_SELECTARG1 |
5528 WINED3DTEXOPCAPS_SELECTARG2 |
5529 WINED3DTEXOPCAPS_DISABLE;
5531 if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
5532 GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
5533 GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
5534 pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
5535 WINED3DTEXOPCAPS_BLENDTEXTUREALPHA |
5536 WINED3DTEXOPCAPS_BLENDFACTORALPHA |
5537 WINED3DTEXOPCAPS_BLENDCURRENTALPHA |
5538 WINED3DTEXOPCAPS_LERP |
5539 WINED3DTEXOPCAPS_SUBTRACT;
5541 if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
5542 GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
5543 pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH |
5544 WINED3DTEXOPCAPS_MULTIPLYADD |
5545 WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
5546 WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
5547 WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5549 if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
5550 pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5552 pCaps->MaxTextureBlendStages = GL_LIMITS(texture_stages);
5553 pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
5556 static HRESULT ffp_fragment_alloc(IWineD3DDevice *iface) { return WINED3D_OK; }
5557 static void ffp_fragment_free(IWineD3DDevice *iface) {}
5558 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5560 if (TRACE_ON(d3d))
5562 TRACE("Checking support for fixup:\n");
5563 dump_color_fixup_desc(fixup);
5566 /* We only support identity conversions. */
5567 if (is_identity_fixup(fixup))
5569 TRACE("[OK]\n");
5570 return TRUE;
5573 TRACE("[FAILED]\n");
5574 return FALSE;
5577 const struct fragment_pipeline ffp_fragment_pipeline = {
5578 ffp_enable,
5579 ffp_fragment_get_caps,
5580 ffp_fragment_alloc,
5581 ffp_fragment_free,
5582 ffp_color_fixup_supported,
5583 ffp_fragmentstate_template,
5584 FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5587 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5589 unsigned int i;
5590 for(i = 0; funcs[i]; i++);
5591 return i;
5594 static void multistate_apply_2(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
5596 stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
5597 stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
5600 static void multistate_apply_3(DWORD state, IWineD3DStateBlockImpl *stateblock, struct wined3d_context *context)
5602 stateblock->wineD3DDevice->multistate_funcs[state][0](state, stateblock, context);
5603 stateblock->wineD3DDevice->multistate_funcs[state][1](state, stateblock, context);
5604 stateblock->wineD3DDevice->multistate_funcs[state][2](state, stateblock, context);
5607 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5608 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5609 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5611 unsigned int i, type, handlers;
5612 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5613 const struct StateEntryTemplate *cur;
5614 BOOL set[STATE_HIGHEST + 1];
5616 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5618 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5619 StateTable[i].representative = 0;
5620 StateTable[i].apply = state_undefined;
5623 for(type = 0; type < 3; type++) {
5624 /* This switch decides the order in which the states are applied */
5625 switch(type) {
5626 case 0: cur = misc; break;
5627 case 1: cur = fragment->states; break;
5628 case 2: cur = vertex; break;
5629 default: cur = NULL; /* Stupid compiler */
5631 if(!cur) continue;
5633 /* GL extension filtering should not prevent multiple handlers being applied from different
5634 * pipeline parts
5636 memset(set, 0, sizeof(set));
5638 for(i = 0; cur[i].state; i++) {
5639 APPLYSTATEFUNC *funcs_array;
5641 /* Only use the first matching state with the available extension from one template.
5642 * e.g.
5643 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5644 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5646 * if GL_XYZ_fancy is supported, ignore the 2nd line
5648 if(set[cur[i].state]) continue;
5649 /* Skip state lines depending on unsupported extensions */
5650 if (!GL_SUPPORT(cur[i].extension)) continue;
5651 set[cur[i].state] = TRUE;
5652 /* In some cases having an extension means that nothing has to be
5653 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5654 * supported, the texture coordinate fixup can be ignored. If the
5655 * apply function is used, mark the state set(done above) to prevent
5656 * applying later lines, but do not record anything in the state
5657 * table
5659 if(!cur[i].content.apply) continue;
5661 handlers = num_handlers(multistate_funcs[cur[i].state]);
5662 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5663 switch(handlers) {
5664 case 0:
5665 StateTable[cur[i].state].apply = cur[i].content.apply;
5666 break;
5667 case 1:
5668 StateTable[cur[i].state].apply = multistate_apply_2;
5669 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5671 sizeof(**dev_multistate_funcs) * 2);
5672 if (!dev_multistate_funcs[cur[i].state]) {
5673 goto out_of_mem;
5676 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5677 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5678 break;
5679 case 2:
5680 StateTable[cur[i].state].apply = multistate_apply_3;
5681 funcs_array = HeapReAlloc(GetProcessHeap(),
5683 dev_multistate_funcs[cur[i].state],
5684 sizeof(**dev_multistate_funcs) * 3);
5685 if (!funcs_array) {
5686 goto out_of_mem;
5689 dev_multistate_funcs[cur[i].state] = funcs_array;
5690 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5691 break;
5692 default:
5693 ERR("Unexpected amount of state handlers for state %u: %u\n",
5694 cur[i].state, handlers + 1);
5697 if(StateTable[cur[i].state].representative &&
5698 StateTable[cur[i].state].representative != cur[i].content.representative) {
5699 FIXME("State %u has different representatives in different pipeline parts\n",
5700 cur[i].state);
5702 StateTable[cur[i].state].representative = cur[i].content.representative;
5706 return WINED3D_OK;
5708 out_of_mem:
5709 for (i = 0; i <= STATE_HIGHEST; ++i) {
5710 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5713 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5715 return E_OUTOFMEMORY;
5717 #undef GLINFO_LOCATION