wined3d: Introduce a wined3d_vertex_pipe_ops structure.
[wine/multimedia.git] / dlls / wined3d / state.c
blob84e8b72620c46002e90193c76d95256104d89876
1 /*
2 * Direct3D state management
4 * Copyright 2002 Lionel Ulmer
5 * Copyright 2002-2005 Jason Edmeades
6 * Copyright 2003-2004 Raphael Junqueira
7 * Copyright 2004 Christian Costa
8 * Copyright 2005 Oliver Stieber
9 * Copyright 2006 Henri Verbeet
10 * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
11 * Copyright 2009-2011 Henri Verbeet for CodeWeavers
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "config.h"
29 #include "wine/port.h"
31 #include <stdio.h>
32 #ifdef HAVE_FLOAT_H
33 # include <float.h>
34 #endif
36 #include "wined3d_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
39 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
41 /* Context activation for state handler is done by the caller. */
43 static void state_undefined(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
45 ERR("Undefined state.\n");
48 static void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
50 TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state_id));
53 static void state_fillmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
55 enum wined3d_fill_mode mode = state->render_states[WINED3D_RS_FILLMODE];
56 const struct wined3d_gl_info *gl_info = context->gl_info;
58 switch (mode)
60 case WINED3D_FILL_POINT:
61 gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
62 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
63 break;
64 case WINED3D_FILL_WIREFRAME:
65 gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
66 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
67 break;
68 case WINED3D_FILL_SOLID:
69 gl_info->gl_ops.gl.p_glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
70 checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
71 break;
72 default:
73 FIXME("Unrecognized fill mode %#x.\n", mode);
77 static void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
79 const struct wined3d_gl_info *gl_info = context->gl_info;
81 /* Lighting is not enabled if transformed vertices are drawn, but lighting
82 * does not affect the stream sources, so it is not grouped for
83 * performance reasons. This state reads the decoded vertex declaration,
84 * so if it is dirty don't do anything. The vertex declaration applying
85 * function calls this function for updating. */
86 if (isStateDirty(context, STATE_VDECL))
87 return;
89 if (state->render_states[WINED3D_RS_LIGHTING]
90 && !context->swapchain->device->stream_info.position_transformed)
92 gl_info->gl_ops.gl.p_glEnable(GL_LIGHTING);
93 checkGLcall("glEnable GL_LIGHTING");
95 else
97 gl_info->gl_ops.gl.p_glDisable(GL_LIGHTING);
98 checkGLcall("glDisable GL_LIGHTING");
102 static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
104 enum wined3d_depth_buffer_type zenable = state->render_states[WINED3D_RS_ZENABLE];
105 const struct wined3d_gl_info *gl_info = context->gl_info;
106 static UINT once;
108 /* No z test without depth stencil buffers */
109 if (!state->fb->depth_stencil)
111 TRACE("No Z buffer - disabling depth test\n");
112 zenable = WINED3D_ZB_FALSE;
115 switch (zenable)
117 case WINED3D_ZB_FALSE:
118 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_TEST);
119 checkGLcall("glDisable GL_DEPTH_TEST");
120 break;
121 case WINED3D_ZB_TRUE:
122 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
123 checkGLcall("glEnable GL_DEPTH_TEST");
124 break;
125 case WINED3D_ZB_USEW:
126 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_TEST);
127 checkGLcall("glEnable GL_DEPTH_TEST");
128 FIXME("W buffer is not well handled\n");
129 break;
130 default:
131 FIXME("Unrecognized depth buffer type %#x.\n", zenable);
132 break;
135 if (context->gl_info->supported[ARB_DEPTH_CLAMP])
137 if (!zenable && context->swapchain->device->stream_info.position_transformed)
139 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_CLAMP);
140 checkGLcall("glEnable(GL_DEPTH_CLAMP)");
142 else
144 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_CLAMP);
145 checkGLcall("glDisable(GL_DEPTH_CLAMP)");
148 else if (!zenable && !once++)
149 FIXME("Z buffer disabled, but ARB_depth_clamp isn't supported.\n");
152 static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
154 const struct wined3d_gl_info *gl_info = context->gl_info;
156 /* glFrontFace() is set in context.c at context init and on an
157 * offscreen / onscreen rendering switch. */
158 switch (state->render_states[WINED3D_RS_CULLMODE])
160 case WINED3D_CULL_NONE:
161 gl_info->gl_ops.gl.p_glDisable(GL_CULL_FACE);
162 checkGLcall("glDisable GL_CULL_FACE");
163 break;
164 case WINED3D_CULL_CW:
165 gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE);
166 checkGLcall("glEnable GL_CULL_FACE");
167 gl_info->gl_ops.gl.p_glCullFace(GL_FRONT);
168 checkGLcall("glCullFace(GL_FRONT)");
169 break;
170 case WINED3D_CULL_CCW:
171 gl_info->gl_ops.gl.p_glEnable(GL_CULL_FACE);
172 checkGLcall("glEnable GL_CULL_FACE");
173 gl_info->gl_ops.gl.p_glCullFace(GL_BACK);
174 checkGLcall("glCullFace(GL_BACK)");
175 break;
176 default:
177 FIXME("Unrecognized cull mode %#x.\n",
178 state->render_states[WINED3D_RS_CULLMODE]);
182 static void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
184 const struct wined3d_gl_info *gl_info = context->gl_info;
186 switch (state->render_states[WINED3D_RS_SHADEMODE])
188 case WINED3D_SHADE_FLAT:
189 gl_info->gl_ops.gl.p_glShadeModel(GL_FLAT);
190 checkGLcall("glShadeModel(GL_FLAT)");
191 break;
192 case WINED3D_SHADE_GOURAUD:
193 gl_info->gl_ops.gl.p_glShadeModel(GL_SMOOTH);
194 checkGLcall("glShadeModel(GL_SMOOTH)");
195 break;
196 case WINED3D_SHADE_PHONG:
197 FIXME("WINED3D_SHADE_PHONG isn't supported.\n");
198 break;
199 default:
200 FIXME("Unrecognized shade mode %#x.\n",
201 state->render_states[WINED3D_RS_SHADEMODE]);
205 static void state_ditherenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
207 const struct wined3d_gl_info *gl_info = context->gl_info;
209 if (state->render_states[WINED3D_RS_DITHERENABLE])
211 gl_info->gl_ops.gl.p_glEnable(GL_DITHER);
212 checkGLcall("glEnable GL_DITHER");
214 else
216 gl_info->gl_ops.gl.p_glDisable(GL_DITHER);
217 checkGLcall("glDisable GL_DITHER");
221 static void state_zwritenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
223 const struct wined3d_gl_info *gl_info = context->gl_info;
225 if (state->render_states[WINED3D_RS_ZWRITEENABLE])
227 gl_info->gl_ops.gl.p_glDepthMask(1);
228 checkGLcall("glDepthMask(1)");
230 else
232 gl_info->gl_ops.gl.p_glDepthMask(0);
233 checkGLcall("glDepthMask(0)");
237 static GLenum gl_compare_func(enum wined3d_cmp_func f)
239 switch (f)
241 case WINED3D_CMP_NEVER:
242 return GL_NEVER;
243 case WINED3D_CMP_LESS:
244 return GL_LESS;
245 case WINED3D_CMP_EQUAL:
246 return GL_EQUAL;
247 case WINED3D_CMP_LESSEQUAL:
248 return GL_LEQUAL;
249 case WINED3D_CMP_GREATER:
250 return GL_GREATER;
251 case WINED3D_CMP_NOTEQUAL:
252 return GL_NOTEQUAL;
253 case WINED3D_CMP_GREATEREQUAL:
254 return GL_GEQUAL;
255 case WINED3D_CMP_ALWAYS:
256 return GL_ALWAYS;
257 default:
258 FIXME("Unrecognized compare function %#x.\n", f);
259 return GL_NONE;
263 static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
265 GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
266 const struct wined3d_gl_info *gl_info = context->gl_info;
268 if (!depth_func) return;
270 if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL)
272 static BOOL once;
273 /* There are a few issues with this: First, our inability to
274 * select a proper Z depth, most of the time we're stuck with
275 * D24S8, even if the app selects D32 or D16. There seem to be
276 * some other precision problems which have to be debugged to
277 * make NOTEQUAL and EQUAL work properly. */
278 if (!once)
280 once = TRUE;
281 FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet.\n");
285 gl_info->gl_ops.gl.p_glDepthFunc(depth_func);
286 checkGLcall("glDepthFunc");
289 static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
291 const struct wined3d_gl_info *gl_info = context->gl_info;
292 float col[4];
294 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col);
295 TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
296 gl_info->gl_ops.gl.p_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
297 checkGLcall("glLightModel for MODEL_AMBIENT");
300 static void state_blendop_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
302 WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
305 static GLenum gl_blend_op(enum wined3d_blend_op op)
307 switch (op)
309 case WINED3D_BLEND_OP_ADD:
310 return GL_FUNC_ADD_EXT;
311 case WINED3D_BLEND_OP_SUBTRACT:
312 return GL_FUNC_SUBTRACT_EXT;
313 case WINED3D_BLEND_OP_REVSUBTRACT:
314 return GL_FUNC_REVERSE_SUBTRACT_EXT;
315 case WINED3D_BLEND_OP_MIN:
316 return GL_MIN_EXT;
317 case WINED3D_BLEND_OP_MAX:
318 return GL_MAX_EXT;
319 default:
320 FIXME("Unhandled blend op %#x.\n", op);
321 return GL_NONE;
325 static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
327 const struct wined3d_gl_info *gl_info = context->gl_info;
328 GLenum blend_equation_alpha = GL_FUNC_ADD_EXT;
329 GLenum blend_equation = GL_FUNC_ADD_EXT;
331 /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
332 if (state->render_states[WINED3D_RS_BLENDOPALPHA]
333 && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
335 WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
336 return;
339 blend_equation = gl_blend_op(state->render_states[WINED3D_RS_BLENDOP]);
340 blend_equation_alpha = gl_blend_op(state->render_states[WINED3D_RS_BLENDOPALPHA]);
341 TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
343 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
345 GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
346 checkGLcall("glBlendEquationSeparateEXT");
348 else
350 GL_EXTCALL(glBlendEquationEXT(blend_equation));
351 checkGLcall("glBlendEquation");
355 static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_format *dst_format)
357 switch (factor)
359 case WINED3D_BLEND_ZERO:
360 return GL_ZERO;
361 case WINED3D_BLEND_ONE:
362 return GL_ONE;
363 case WINED3D_BLEND_SRCCOLOR:
364 return GL_SRC_COLOR;
365 case WINED3D_BLEND_INVSRCCOLOR:
366 return GL_ONE_MINUS_SRC_COLOR;
367 case WINED3D_BLEND_SRCALPHA:
368 return GL_SRC_ALPHA;
369 case WINED3D_BLEND_INVSRCALPHA:
370 return GL_ONE_MINUS_SRC_ALPHA;
371 case WINED3D_BLEND_DESTCOLOR:
372 return GL_DST_COLOR;
373 case WINED3D_BLEND_INVDESTCOLOR:
374 return GL_ONE_MINUS_DST_COLOR;
375 /* To compensate for the lack of format switching with backbuffer
376 * offscreen rendering, and with onscreen rendering, we modify the
377 * alpha test parameters for (INV)DESTALPHA if the render target
378 * doesn't support alpha blending. A nonexistent alpha channel
379 * returns 1.0, so WINED3D_BLEND_DESTALPHA becomes GL_ONE, and
380 * WINED3D_BLEND_INVDESTALPHA becomes GL_ZERO. */
381 case WINED3D_BLEND_DESTALPHA:
382 return dst_format->alpha_size ? GL_DST_ALPHA : GL_ONE;
383 case WINED3D_BLEND_INVDESTALPHA:
384 return dst_format->alpha_size ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
385 case WINED3D_BLEND_SRCALPHASAT:
386 return GL_SRC_ALPHA_SATURATE;
387 case WINED3D_BLEND_BLENDFACTOR:
388 return GL_CONSTANT_COLOR_EXT;
389 case WINED3D_BLEND_INVBLENDFACTOR:
390 return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
391 default:
392 FIXME("Unhandled blend factor %#x.\n", factor);
393 return GL_NONE;
397 static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
399 const struct wined3d_surface *target = state->fb->render_targets[0];
400 const struct wined3d_gl_info *gl_info = context->gl_info;
401 GLenum srcBlend, dstBlend;
402 enum wined3d_blend d3d_blend;
404 /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
405 * blending parameters to work. */
406 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]
407 || state->render_states[WINED3D_RS_EDGEANTIALIAS]
408 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
410 /* Disable blending in all cases even without pixelshaders.
411 * With blending on we could face a big performance penalty.
412 * The d3d9 visual test confirms the behavior. */
413 if (context->render_offscreen
414 && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
416 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
417 checkGLcall("glDisable GL_BLEND");
418 return;
420 else
422 gl_info->gl_ops.gl.p_glEnable(GL_BLEND);
423 checkGLcall("glEnable GL_BLEND");
426 else
428 gl_info->gl_ops.gl.p_glDisable(GL_BLEND);
429 checkGLcall("glDisable GL_BLEND");
430 /* Nothing more to do - get out */
431 return;
434 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
435 * source blending values which are still valid up to d3d9. They should
436 * not occur as dest blend values. */
437 d3d_blend = state->render_states[WINED3D_RS_SRCBLEND];
438 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
440 srcBlend = GL_SRC_ALPHA;
441 dstBlend = GL_ONE_MINUS_SRC_ALPHA;
443 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
445 srcBlend = GL_ONE_MINUS_SRC_ALPHA;
446 dstBlend = GL_SRC_ALPHA;
448 else
450 srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
451 dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
452 target->resource.format);
455 if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
456 || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
458 gl_info->gl_ops.gl.p_glEnable(GL_LINE_SMOOTH);
459 checkGLcall("glEnable(GL_LINE_SMOOTH)");
460 if (srcBlend != GL_SRC_ALPHA)
461 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param.\n");
462 if (dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE)
463 WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param.\n");
465 else
467 gl_info->gl_ops.gl.p_glDisable(GL_LINE_SMOOTH);
468 checkGLcall("glDisable(GL_LINE_SMOOTH)");
471 /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
472 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP)))
473 state_blendop(context, state, STATE_RENDER(WINED3D_RS_BLENDOPALPHA));
475 if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
477 GLenum srcBlendAlpha, dstBlendAlpha;
479 /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
480 if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
482 WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
483 return;
486 /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
487 * source blending values which are still valid up to d3d9. They should
488 * not occur as dest blend values. */
489 d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA];
490 if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
492 srcBlendAlpha = GL_SRC_ALPHA;
493 dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
495 else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
497 srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
498 dstBlendAlpha = GL_SRC_ALPHA;
500 else
502 srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
503 dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
504 target->resource.format);
507 GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
508 checkGLcall("glBlendFuncSeparateEXT");
510 else
512 TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
513 gl_info->gl_ops.gl.p_glBlendFunc(srcBlend, dstBlend);
514 checkGLcall("glBlendFunc");
517 /* Colorkey fixup for stage 0 alphaop depends on
518 * WINED3D_RS_ALPHABLENDENABLE state, so it may need updating. */
519 if (state->render_states[WINED3D_RS_COLORKEYENABLE])
520 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
523 static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
525 WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
528 static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
530 const struct wined3d_gl_info *gl_info = context->gl_info;
531 float col[4];
533 TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
535 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
536 GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
537 checkGLcall("glBlendColor");
540 static void state_alpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
542 const struct wined3d_gl_info *gl_info = context->gl_info;
543 int glParm = 0;
544 float ref;
545 BOOL enable_ckey = FALSE;
547 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
549 /* Find out if the texture on the first stage has a ckey set
550 * The alpha state func reads the texture settings, even though alpha and texture are not grouped
551 * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
552 * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
553 * in case it finds some texture+colorkeyenable combination which needs extra care.
555 if (state->textures[0])
557 struct wined3d_surface *surface = surface_from_resource(state->textures[0]->sub_resources[0]);
559 if (surface->CKeyFlags & WINEDDSD_CKSRCBLT)
560 enable_ckey = TRUE;
563 if (enable_ckey || context->last_was_ckey)
564 context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
565 context->last_was_ckey = enable_ckey;
567 if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
568 || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
570 gl_info->gl_ops.gl.p_glEnable(GL_ALPHA_TEST);
571 checkGLcall("glEnable GL_ALPHA_TEST");
573 else
575 gl_info->gl_ops.gl.p_glDisable(GL_ALPHA_TEST);
576 checkGLcall("glDisable GL_ALPHA_TEST");
577 /* Alpha test is disabled, don't bother setting the params - it will happen on the next
578 * enable call
580 return;
583 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
585 glParm = GL_NOTEQUAL;
586 ref = 0.0f;
588 else
590 ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
591 glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
593 if (glParm)
595 gl_info->gl_ops.gl.p_glAlphaFunc(glParm, ref);
596 checkGLcall("glAlphaFunc");
600 static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
602 context->load_constants = 1;
605 static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
607 const struct wined3d_gl_info *gl_info = context->gl_info;
608 DWORD enable = 0xffffffff;
609 DWORD disable = 0x00000000;
611 if (use_vs(state))
613 const struct wined3d_device *device = context->swapchain->device;
615 if (!device->vs_clipping)
617 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
618 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
619 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
620 * of that - don't do anything here and keep them disabled
622 if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
624 static BOOL warned = FALSE;
625 if(!warned) {
626 FIXME("Clipping not supported with vertex shaders\n");
627 warned = TRUE;
630 return;
633 /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
634 * hardcoded into the shader. Update the shader to update the enabled clipplanes */
635 context->select_shader = 1;
636 context->load_constants = 1;
639 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
640 * of already set values
643 /* If enabling / disabling all
644 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
646 if (state->render_states[WINED3D_RS_CLIPPING])
648 enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
649 disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
651 else
653 disable = 0xffffffff;
654 enable = 0x00;
657 if (enable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE0);
658 if (enable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE1);
659 if (enable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE2);
660 if (enable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE3);
661 if (enable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE4);
662 if (enable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE5);
663 checkGLcall("clip plane enable");
665 if (disable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0);
666 if (disable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1);
667 if (disable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2);
668 if (disable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3);
669 if (disable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4);
670 if (disable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5);
671 checkGLcall("clip plane disable");
674 static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
676 const struct wined3d_gl_info *gl_info = context->gl_info;
677 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
678 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
679 * specular color. This is wrong:
680 * Separate specular color means the specular colour is maintained separately, whereas
681 * single color means it is merged in. However in both cases they are being used to
682 * some extent.
683 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
684 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
685 * running 1.4 yet!
688 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
689 * Instead, we need to setup the FinalCombiner properly.
691 * The default setup for the FinalCombiner is:
693 * <variable> <input> <mapping> <usage>
694 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
695 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
696 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
697 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
698 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
699 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
700 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
702 * That's pretty much fine as it is, except for variable B, which needs to take
703 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
704 * whether WINED3D_RS_SPECULARENABLE is enabled or not.
707 TRACE("Setting specular enable state and materials\n");
708 if (state->render_states[WINED3D_RS_SPECULARENABLE])
710 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
711 checkGLcall("glMaterialfv");
713 if (state->material.power > gl_info->limits.shininess)
715 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
716 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
717 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
718 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
719 * them, it should be safe to do so without major visual distortions.
721 WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
722 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
724 else
726 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
728 checkGLcall("glMaterialf(GL_SHININESS)");
730 if (gl_info->supported[EXT_SECONDARY_COLOR])
731 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_SUM_EXT);
732 else
733 TRACE("Specular colors cannot be enabled in this version of opengl\n");
734 checkGLcall("glEnable(GL_COLOR_SUM)");
736 if (gl_info->supported[NV_REGISTER_COMBINERS])
738 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
739 checkGLcall("glFinalCombinerInputNV()");
741 } else {
742 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
744 /* for the case of enabled lighting: */
745 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
746 checkGLcall("glMaterialfv");
748 /* for the case of disabled lighting: */
749 if (gl_info->supported[EXT_SECONDARY_COLOR])
750 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
751 else
752 TRACE("Specular colors cannot be disabled in this version of opengl\n");
753 checkGLcall("glDisable(GL_COLOR_SUM)");
755 if (gl_info->supported[NV_REGISTER_COMBINERS])
757 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
758 checkGLcall("glFinalCombinerInputNV()");
762 TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
763 state->material.diffuse.r, state->material.diffuse.g,
764 state->material.diffuse.b, state->material.diffuse.a);
765 TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
766 state->material.ambient.r, state->material.ambient.g,
767 state->material.ambient.b, state->material.ambient.a);
768 TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
769 state->material.specular.r, state->material.specular.g,
770 state->material.specular.b, state->material.specular.a);
771 TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
772 state->material.emissive.r, state->material.emissive.g,
773 state->material.emissive.b, state->material.emissive.a);
775 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
776 checkGLcall("glMaterialfv(GL_AMBIENT)");
777 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
778 checkGLcall("glMaterialfv(GL_DIFFUSE)");
779 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
780 checkGLcall("glMaterialfv(GL_EMISSION)");
783 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
785 const struct wined3d_gl_info *gl_info = context->gl_info;
786 unsigned int i;
788 /* Note the texture color applies to all textures whereas
789 * GL_TEXTURE_ENV_COLOR applies to active only. */
790 float col[4];
791 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
793 /* And now the default texture color as well */
794 for (i = 0; i < gl_info->limits.texture_stages; ++i)
796 /* Note the WINED3D_RS value applies to all textures, but GL has one
797 * per texture, so apply it now ready to be used! */
798 context_active_texture(context, gl_info, i);
800 gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
801 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
805 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
806 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
808 const struct wined3d_gl_info *gl_info = context->gl_info;
810 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
811 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
812 GL_EXTCALL(glActiveStencilFaceEXT(face));
813 checkGLcall("glActiveStencilFaceEXT(...)");
814 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
815 checkGLcall("glStencilFunc(...)");
816 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
817 checkGLcall("glStencilOp(...)");
820 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
822 switch (op)
824 case WINED3D_STENCIL_OP_KEEP:
825 return GL_KEEP;
826 case WINED3D_STENCIL_OP_ZERO:
827 return GL_ZERO;
828 case WINED3D_STENCIL_OP_REPLACE:
829 return GL_REPLACE;
830 case WINED3D_STENCIL_OP_INCR_SAT:
831 return GL_INCR;
832 case WINED3D_STENCIL_OP_DECR_SAT:
833 return GL_DECR;
834 case WINED3D_STENCIL_OP_INVERT:
835 return GL_INVERT;
836 case WINED3D_STENCIL_OP_INCR:
837 return GL_INCR_WRAP_EXT;
838 case WINED3D_STENCIL_OP_DECR:
839 return GL_DECR_WRAP_EXT;
840 default:
841 FIXME("Unrecognized stencil op %#x.\n", op);
842 return GL_KEEP;
846 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
848 const struct wined3d_gl_info *gl_info = context->gl_info;
849 DWORD onesided_enable = FALSE;
850 DWORD twosided_enable = FALSE;
851 GLint func = GL_ALWAYS;
852 GLint func_ccw = GL_ALWAYS;
853 GLint ref = 0;
854 GLuint mask = 0;
855 GLint stencilFail = GL_KEEP;
856 GLint depthFail = GL_KEEP;
857 GLint stencilPass = GL_KEEP;
858 GLint stencilFail_ccw = GL_KEEP;
859 GLint depthFail_ccw = GL_KEEP;
860 GLint stencilPass_ccw = GL_KEEP;
862 /* No stencil test without a stencil buffer. */
863 if (!state->fb->depth_stencil)
865 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
866 checkGLcall("glDisable GL_STENCIL_TEST");
867 return;
870 onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
871 twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
872 if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
873 func = GL_ALWAYS;
874 if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
875 func_ccw = GL_ALWAYS;
876 ref = state->render_states[WINED3D_RS_STENCILREF];
877 mask = state->render_states[WINED3D_RS_STENCILMASK];
878 stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
879 depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
880 stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
881 stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
882 depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
883 stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
885 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
886 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
887 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
888 onesided_enable, twosided_enable, ref, mask,
889 func, stencilFail, depthFail, stencilPass,
890 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
892 if (twosided_enable && onesided_enable)
894 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
895 checkGLcall("glEnable GL_STENCIL_TEST");
897 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
899 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
900 * which has an effect on the code below too. If we apply the front face
901 * afterwards, we are sure that the active stencil face is set to front,
902 * and other stencil functions which do not use two sided stencil do not have
903 * to set it back
905 renderstate_stencil_twosided(context, GL_BACK,
906 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
907 renderstate_stencil_twosided(context, GL_FRONT,
908 func, ref, mask, stencilFail, depthFail, stencilPass);
910 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
912 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
913 checkGLcall("glStencilFuncSeparateATI(...)");
914 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
915 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
916 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
917 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
918 } else {
919 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
922 else if(onesided_enable)
924 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
926 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
927 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
930 /* This code disables the ATI extension as well, since the standard stencil functions are equal
931 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
933 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
934 checkGLcall("glEnable GL_STENCIL_TEST");
935 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
936 checkGLcall("glStencilFunc(...)");
937 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
938 checkGLcall("glStencilOp(...)");
940 else
942 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
943 checkGLcall("glDisable GL_STENCIL_TEST");
947 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
949 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
950 const struct wined3d_gl_info *gl_info = context->gl_info;
952 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
953 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
954 gl_info->gl_ops.gl.p_glStencilMask(mask);
955 checkGLcall("glStencilMask");
956 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
957 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
958 gl_info->gl_ops.gl.p_glStencilMask(mask);
961 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
963 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
964 const struct wined3d_gl_info *gl_info = context->gl_info;
966 gl_info->gl_ops.gl.p_glStencilMask(mask);
967 checkGLcall("glStencilMask");
970 static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
972 const struct wined3d_gl_info *gl_info = context->gl_info;
974 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
976 if (!state->render_states[WINED3D_RS_FOGENABLE])
977 return;
979 /* Table fog on: Never use fog coords, and use per-fragment fog */
980 if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
982 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST);
983 if (context->fog_coord)
985 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
986 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
987 context->fog_coord = FALSE;
990 /* Range fog is only used with per-vertex fog in d3d */
991 if (gl_info->supported[NV_FOG_DISTANCE])
993 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
994 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
996 return;
999 /* Otherwise use per-vertex fog in any case */
1000 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_FASTEST);
1002 if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
1004 /* No fog at all, or transformed vertices: Use fog coord */
1005 if (!context->fog_coord)
1007 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1008 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
1009 context->fog_coord = TRUE;
1012 else
1014 /* Otherwise, use the fragment depth */
1015 if (context->fog_coord)
1017 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1018 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1019 context->fog_coord = FALSE;
1022 if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
1024 if (gl_info->supported[NV_FOG_DISTANCE])
1026 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1027 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1029 else
1031 WARN("Range fog enabled, but not supported by this GL implementation.\n");
1034 else if (gl_info->supported[NV_FOG_DISTANCE])
1036 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1037 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1042 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1044 const struct wined3d_gl_info *gl_info = context->gl_info;
1045 float fogstart, fogend;
1046 union {
1047 DWORD d;
1048 float f;
1049 } tmpvalue;
1051 switch(context->fog_source) {
1052 case FOGSOURCE_VS:
1053 fogstart = 1.0f;
1054 fogend = 0.0f;
1055 break;
1057 case FOGSOURCE_COORD:
1058 fogstart = 255.0f;
1059 fogend = 0.0f;
1060 break;
1062 case FOGSOURCE_FFP:
1063 tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
1064 fogstart = tmpvalue.f;
1065 tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
1066 fogend = tmpvalue.f;
1067 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
1068 if(fogstart == fogend) {
1069 fogstart = -INFINITY;
1070 fogend = 0.0f;
1072 break;
1074 default:
1075 /* This should not happen.context->fog_source is set in wined3d, not the app.
1076 * Still this is needed to make the compiler happy
1078 ERR("Unexpected fog coordinate source\n");
1079 fogstart = 0.0f;
1080 fogend = 0.0f;
1083 gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, fogstart);
1084 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1085 TRACE("Fog Start == %f\n", fogstart);
1087 gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, fogend);
1088 checkGLcall("glFogf(GL_FOG_END, fogend)");
1089 TRACE("Fog End == %f\n", fogend);
1092 void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1094 const struct wined3d_gl_info *gl_info = context->gl_info;
1095 enum fogsource new_source;
1097 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
1099 if (!state->render_states[WINED3D_RS_FOGENABLE])
1101 /* No fog? Disable it, and we're done :-) */
1102 glDisableWINE(GL_FOG);
1103 checkGLcall("glDisable GL_FOG");
1104 return;
1107 /* Fog Rules:
1109 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1110 * It can use the Z value of the vertex, or the alpha component of the specular color.
1111 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1112 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1113 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1115 * FOGTABLEMODE != NONE:
1116 * The Z value is used, with the equation specified, no matter what vertex type.
1118 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1119 * Per vertex fog is calculated using the specified fog equation and the parameters
1121 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1122 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1123 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1126 * Rules for vertex fog with shaders:
1128 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1129 * the fog computation to happen during transformation while openGL expects it to happen
1130 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1131 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1132 * To solve this problem, WineD3D does:
1133 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1134 * shader,
1135 * and 2) disables the fog computation (in either the fixed function or programmable
1136 * rasterizer) if using a vertex program.
1138 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1139 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1140 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1141 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1142 * There are some GL differences between specular fog coords and vertex shaders though.
1144 * With table fog the vertex shader fog coordinate is ignored.
1146 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1147 * without shaders).
1150 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1151 * the system will apply only pixel(=table) fog effects."
1153 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
1155 if (use_vs(state))
1157 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1158 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1159 new_source = FOGSOURCE_VS;
1161 else
1163 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
1165 /* If processed vertices are used, fall through to the NONE case */
1166 case WINED3D_FOG_EXP:
1167 if (!context->last_was_rhw)
1169 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1170 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1171 new_source = FOGSOURCE_FFP;
1172 break;
1174 /* drop through */
1176 case WINED3D_FOG_EXP2:
1177 if (!context->last_was_rhw)
1179 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1180 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1181 new_source = FOGSOURCE_FFP;
1182 break;
1184 /* drop through */
1186 case WINED3D_FOG_LINEAR:
1187 if (!context->last_was_rhw)
1189 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1190 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1191 new_source = FOGSOURCE_FFP;
1192 break;
1194 /* drop through */
1196 case WINED3D_FOG_NONE:
1197 /* Both are none? According to msdn the alpha channel of the specular
1198 * color contains a fog factor. Set it in drawStridedSlow.
1199 * Same happens with Vertexfog on transformed vertices
1201 new_source = FOGSOURCE_COORD;
1202 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1203 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1204 break;
1206 default:
1207 FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
1208 state->render_states[WINED3D_RS_FOGVERTEXMODE]);
1209 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1212 } else {
1213 new_source = FOGSOURCE_FFP;
1215 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
1217 case WINED3D_FOG_EXP:
1218 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1219 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1220 break;
1222 case WINED3D_FOG_EXP2:
1223 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1224 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1225 break;
1227 case WINED3D_FOG_LINEAR:
1228 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1229 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1230 break;
1232 case WINED3D_FOG_NONE: /* Won't happen */
1233 default:
1234 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
1235 state->render_states[WINED3D_RS_FOGTABLEMODE]);
1239 glEnableWINE(GL_FOG);
1240 checkGLcall("glEnable GL_FOG");
1241 if (new_source != context->fog_source)
1243 context->fog_source = new_source;
1244 state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
1248 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1250 const struct wined3d_gl_info *gl_info = context->gl_info;
1251 float col[4];
1253 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
1254 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, &col[0]);
1255 checkGLcall("glFog GL_FOG_COLOR");
1258 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1260 const struct wined3d_gl_info *gl_info = context->gl_info;
1261 union {
1262 DWORD d;
1263 float f;
1264 } tmpvalue;
1266 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1267 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1268 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1271 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1273 const struct wined3d_device *device = context->swapchain->device;
1274 const struct wined3d_gl_info *gl_info = context->gl_info;
1275 GLenum Parm = 0;
1277 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1278 * The vertex declaration will call this function if the fixed function pipeline is used.
1281 if(isStateDirty(context, STATE_VDECL)) {
1282 return;
1285 context->num_untracked_materials = 0;
1286 if ((device->stream_info.use_map & (1 << WINED3D_FFP_DIFFUSE))
1287 && state->render_states[WINED3D_RS_COLORVERTEX])
1289 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1290 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
1291 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
1292 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
1293 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
1295 if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1297 if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1298 Parm = GL_AMBIENT_AND_DIFFUSE;
1299 else
1300 Parm = GL_DIFFUSE;
1301 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1303 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1304 context->num_untracked_materials++;
1306 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1308 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1309 context->num_untracked_materials++;
1312 else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1314 Parm = GL_AMBIENT;
1315 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1317 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1318 context->num_untracked_materials++;
1320 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1322 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1323 context->num_untracked_materials++;
1326 else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1328 Parm = GL_EMISSION;
1329 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1331 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1332 context->num_untracked_materials++;
1335 else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1337 Parm = GL_SPECULAR;
1341 /* Nothing changed, return. */
1342 if (Parm == context->tracking_parm) return;
1344 if (!Parm)
1346 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_MATERIAL);
1347 checkGLcall("glDisable GL_COLOR_MATERIAL");
1349 else
1351 gl_info->gl_ops.gl.p_glColorMaterial(GL_FRONT_AND_BACK, Parm);
1352 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1353 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_MATERIAL);
1354 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1357 /* Apparently calls to glMaterialfv are ignored for properties we're
1358 * tracking with glColorMaterial, so apply those here. */
1359 switch (context->tracking_parm)
1361 case GL_AMBIENT_AND_DIFFUSE:
1362 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1363 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1364 checkGLcall("glMaterialfv");
1365 break;
1367 case GL_DIFFUSE:
1368 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1369 checkGLcall("glMaterialfv");
1370 break;
1372 case GL_AMBIENT:
1373 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1374 checkGLcall("glMaterialfv");
1375 break;
1377 case GL_EMISSION:
1378 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
1379 checkGLcall("glMaterialfv");
1380 break;
1382 case GL_SPECULAR:
1383 /* Only change material color if specular is enabled, otherwise it is set to black */
1384 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1386 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
1387 checkGLcall("glMaterialfv");
1389 else
1391 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1392 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1393 checkGLcall("glMaterialfv");
1395 break;
1398 context->tracking_parm = Parm;
1401 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1403 const struct wined3d_gl_info *gl_info = context->gl_info;
1404 union
1406 DWORD d;
1407 struct wined3d_line_pattern lp;
1408 } tmppattern;
1409 tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
1411 TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1413 if (tmppattern.lp.repeat_factor)
1415 gl_info->gl_ops.gl.p_glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1416 checkGLcall("glLineStipple(repeat, linepattern)");
1417 gl_info->gl_ops.gl.p_glEnable(GL_LINE_STIPPLE);
1418 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1420 else
1422 gl_info->gl_ops.gl.p_glDisable(GL_LINE_STIPPLE);
1423 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1427 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1429 const struct wined3d_gl_info *gl_info = context->gl_info;
1431 if (isStateDirty(context, STATE_VDECL))
1432 return;
1434 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1435 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1436 * by zero and is not properly defined in opengl, so avoid it
1438 if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
1439 && (context->swapchain->device->stream_info.use_map & (1 << WINED3D_FFP_NORMAL)))
1441 gl_info->gl_ops.gl.p_glEnable(GL_NORMALIZE);
1442 checkGLcall("glEnable(GL_NORMALIZE);");
1444 else
1446 gl_info->gl_ops.gl.p_glDisable(GL_NORMALIZE);
1447 checkGLcall("glDisable(GL_NORMALIZE);");
1451 static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1453 union {
1454 DWORD d;
1455 float f;
1456 } tmpvalue;
1458 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1459 if (tmpvalue.f != 1.0f)
1461 FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1463 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1464 if (tmpvalue.f != 64.0f)
1466 FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1471 static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1473 const struct wined3d_gl_info *gl_info = context->gl_info;
1474 union
1476 DWORD d;
1477 float f;
1478 } min, max;
1480 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1481 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1483 /* Max point size trumps min point size */
1484 if(min.f > max.f) {
1485 min.f = max.f;
1488 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1489 checkGLcall("glPointParameterfEXT(...)");
1490 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1491 checkGLcall("glPointParameterfEXT(...)");
1494 static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1496 const struct wined3d_gl_info *gl_info = context->gl_info;
1497 union
1499 DWORD d;
1500 float f;
1501 } min, max;
1503 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1504 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1506 /* Max point size trumps min point size */
1507 if(min.f > max.f) {
1508 min.f = max.f;
1511 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1512 checkGLcall("glPointParameterfARB(...)");
1513 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1514 checkGLcall("glPointParameterfARB(...)");
1517 static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1519 const struct wined3d_gl_info *gl_info = context->gl_info;
1520 /* TODO: Group this with the viewport */
1522 * POINTSCALEENABLE controls how point size value is treated. If set to
1523 * true, the point size is scaled with respect to height of viewport.
1524 * When set to false point size is in pixels.
1527 /* Default values */
1528 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1529 union {
1530 DWORD d;
1531 float f;
1532 } pointSize, A, B, C;
1534 pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
1535 A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
1536 B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
1537 C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
1539 if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1541 DWORD h = state->viewport.height;
1542 GLfloat scaleFactor;
1544 if (pointSize.f < gl_info->limits.pointsize_min)
1546 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1547 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1548 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1549 * are less than 1.0f. scale_factor = 1.0f / point_size.
1551 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1552 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1553 * is 1.0, but then accepts points below that and draws too small points
1555 pointSize.f = gl_info->limits.pointsize_min;
1557 else if(pointSize.f > gl_info->limits.pointsize_max)
1559 /* gl already scales the input to glPointSize,
1560 * d3d scales the result after the point size scale.
1561 * If the point size is bigger than the max size, use the
1562 * scaling to scale it bigger, and set the gl point size to max
1564 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1565 TRACE("scale: %f\n", scaleFactor);
1566 pointSize.f = gl_info->limits.pointsize_max;
1567 } else {
1568 scaleFactor = 1.0f;
1570 scaleFactor = powf(h * scaleFactor, 2);
1572 att[0] = A.f / scaleFactor;
1573 att[1] = B.f / scaleFactor;
1574 att[2] = C.f / scaleFactor;
1577 if (gl_info->supported[ARB_POINT_PARAMETERS])
1579 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1580 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1582 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1584 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1585 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1587 else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1589 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1592 gl_info->gl_ops.gl.p_glPointSize(pointSize.f);
1593 checkGLcall("glPointSize(...);");
1596 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1598 WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
1601 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1603 DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
1604 DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
1605 DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
1606 DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
1607 const struct wined3d_gl_info *gl_info = context->gl_info;
1609 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1610 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1611 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1612 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1613 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1614 gl_info->gl_ops.gl.p_glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1615 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1616 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1617 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1618 checkGLcall("glColorMask(...)");
1620 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1621 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1623 FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1624 mask0, mask1, mask2, mask3);
1625 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1629 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1631 GL_EXTCALL(glColorMaskIndexedEXT(index,
1632 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1633 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1634 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1635 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1638 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1640 set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
1643 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1645 set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
1648 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1650 set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
1653 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1655 set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
1658 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1660 const struct wined3d_gl_info *gl_info = context->gl_info;
1662 if (state->render_states[WINED3D_RS_LOCALVIEWER])
1664 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1665 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1667 else
1669 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1670 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1674 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1676 if (state->render_states[WINED3D_RS_LASTPIXEL])
1678 TRACE("Last Pixel Drawing Enabled\n");
1680 else
1682 static BOOL warned;
1683 if (!warned) {
1684 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1685 warned = TRUE;
1686 } else {
1687 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1692 static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1694 static BOOL warned;
1696 /* TODO: NV_POINT_SPRITE */
1697 if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1699 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1700 FIXME("Point sprites not supported\n");
1701 warned = TRUE;
1705 static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1707 const struct wined3d_gl_info *gl_info = context->gl_info;
1709 if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1711 gl_info->gl_ops.gl.p_glEnable(GL_POINT_SPRITE_ARB);
1712 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1714 else
1716 gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
1717 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1721 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1723 if (state->render_states[WINED3D_RS_WRAP0]
1724 || state->render_states[WINED3D_RS_WRAP1]
1725 || state->render_states[WINED3D_RS_WRAP2]
1726 || state->render_states[WINED3D_RS_WRAP3]
1727 || state->render_states[WINED3D_RS_WRAP4]
1728 || state->render_states[WINED3D_RS_WRAP5]
1729 || state->render_states[WINED3D_RS_WRAP6]
1730 || state->render_states[WINED3D_RS_WRAP7]
1731 || state->render_states[WINED3D_RS_WRAP8]
1732 || state->render_states[WINED3D_RS_WRAP9]
1733 || state->render_states[WINED3D_RS_WRAP10]
1734 || state->render_states[WINED3D_RS_WRAP11]
1735 || state->render_states[WINED3D_RS_WRAP12]
1736 || state->render_states[WINED3D_RS_WRAP13]
1737 || state->render_states[WINED3D_RS_WRAP14]
1738 || state->render_states[WINED3D_RS_WRAP15])
1739 FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
1742 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1744 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1745 WARN("Multisample antialiasing not supported by GL.\n");
1748 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1750 const struct wined3d_gl_info *gl_info = context->gl_info;
1752 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1754 gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE_ARB);
1755 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1757 else
1759 gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE_ARB);
1760 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1764 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1766 const struct wined3d_gl_info *gl_info = context->gl_info;
1768 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
1770 gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST);
1771 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1773 else
1775 gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
1776 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1780 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1781 * OpenGL the bias is specified in units of "the smallest value that is
1782 * guaranteed to produce a resolvable offset for a given implementation". To
1783 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1784 * There's no practical way to retrieve that value from a given GL
1785 * implementation, but the D3D application has essentially the same problem,
1786 * which makes a guess of the depth buffer format's highest possible value a
1787 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1788 * depth slope, and doesn't need to be scaled. */
1789 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1791 const struct wined3d_gl_info *gl_info = context->gl_info;
1793 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
1794 || state->render_states[WINED3D_RS_DEPTHBIAS])
1796 const struct wined3d_surface *depth = state->fb->depth_stencil;
1797 float scale;
1799 union
1801 DWORD d;
1802 float f;
1803 } scale_bias, const_bias;
1805 scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
1806 const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
1808 gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL);
1809 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1811 if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
1813 float bias = -(float)const_bias.d;
1814 gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias);
1815 checkGLcall("glPolygonOffset");
1817 else
1819 if (depth)
1821 const struct wined3d_format *fmt = depth->resource.format;
1822 scale = powf(2, fmt->depth_size) - 1;
1823 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
1824 debug_d3dformat(fmt->id), scale);
1826 else
1828 /* The context manager will reapply this state on a depth stencil change */
1829 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
1830 scale = 0.0f;
1833 gl_info->gl_ops.gl.p_glPolygonOffset(scale_bias.f, const_bias.f * scale);
1834 checkGLcall("glPolygonOffset(...)");
1837 else
1839 gl_info->gl_ops.gl.p_glDisable(GL_POLYGON_OFFSET_FILL);
1840 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1844 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1846 if (state->render_states[WINED3D_RS_ZVISIBLE])
1847 FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
1850 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1852 const struct wined3d_gl_info *gl_info = context->gl_info;
1854 if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
1856 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1857 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1859 else
1861 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1862 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1866 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1868 if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
1869 FIXME("Stippled Alpha not supported yet.\n");
1872 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1874 if (state->render_states[WINED3D_RS_ANTIALIAS])
1875 FIXME("Antialias not supported yet.\n");
1878 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1880 if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
1881 FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
1882 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
1885 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1887 if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
1888 FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
1889 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
1892 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1894 union {
1895 DWORD d;
1896 float f;
1897 } tmpvalue;
1898 tmpvalue.f = 1.0f;
1900 if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
1902 static BOOL displayed = FALSE;
1904 tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
1905 if(!displayed)
1906 FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1908 displayed = TRUE;
1912 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1914 if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
1915 FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
1916 state->render_states[WINED3D_RS_POSITIONDEGREE]);
1919 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1921 if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
1922 FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
1923 state->render_states[WINED3D_RS_NORMALDEGREE]);
1926 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1928 if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
1929 FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1930 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
1933 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1935 union {
1936 DWORD d;
1937 float f;
1938 } zmin, zmax;
1940 const struct wined3d_gl_info *gl_info = context->gl_info;
1942 if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1944 zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
1945 zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
1947 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1948 * In d3d9 test is not performed in this case*/
1949 if (zmin.f <= zmax.f)
1951 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1952 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1953 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1954 checkGLcall("glDepthBoundsEXT(...)");
1956 else
1958 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1959 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1962 else
1964 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1965 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1968 state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
1971 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1973 if (state->render_states[WINED3D_RS_WRAPU])
1974 FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
1977 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1979 if (state->render_states[WINED3D_RS_WRAPV])
1980 FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
1983 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1985 if (state->render_states[WINED3D_RS_MONOENABLE])
1986 FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
1989 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1991 if (state->render_states[WINED3D_RS_ROP2])
1992 FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
1995 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1997 if (state->render_states[WINED3D_RS_PLANEMASK])
1998 FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
2001 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2003 if (state->render_states[WINED3D_RS_SUBPIXEL])
2004 FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
2007 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2009 if (state->render_states[WINED3D_RS_SUBPIXELX])
2010 FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
2013 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2015 if (state->render_states[WINED3D_RS_STIPPLEENABLE])
2016 FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
2019 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2021 if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
2022 FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
2025 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2027 if (state->render_states[WINED3D_RS_ANISOTROPY])
2028 FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
2031 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2033 if (state->render_states[WINED3D_RS_FLUSHBATCH])
2034 FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
2037 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2039 if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
2040 FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
2043 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2045 if (state->render_states[WINED3D_RS_EXTENTS])
2046 FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
2049 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2051 if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
2052 FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
2055 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2057 if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
2058 FIXME("Software vertex processing not implemented.\n");
2061 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2062 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2063 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2064 * flag specifies the complement of the input should be used. */
2065 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2066 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2068 /* Calculate the operand */
2069 if (complement) {
2070 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2071 else *operand = GL_ONE_MINUS_SRC_COLOR;
2072 } else {
2073 if (from_alpha) *operand = GL_SRC_ALPHA;
2074 else *operand = GL_SRC_COLOR;
2077 /* Calculate the source */
2078 switch (arg & WINED3DTA_SELECTMASK) {
2079 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2080 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2081 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2082 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2083 case WINED3DTA_SPECULAR:
2085 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2086 * 'Secondary color' and isn't supported until base GL supports it
2087 * There is no concept of temp registers as far as I can tell
2089 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2090 *source = GL_TEXTURE;
2091 break;
2092 default:
2093 FIXME("Unrecognized texture arg %#x\n", arg);
2094 *source = GL_TEXTURE;
2095 break;
2099 /* Setup the texture operations texture stage states */
2100 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2101 BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2103 GLenum src1, src2, src3;
2104 GLenum opr1, opr2, opr3;
2105 GLenum comb_target;
2106 GLenum src0_target, src1_target, src2_target;
2107 GLenum opr0_target, opr1_target, opr2_target;
2108 GLenum scal_target;
2109 GLenum opr=0, invopr, src3_target, opr3_target;
2110 BOOL Handled = FALSE;
2112 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2114 /* This is called by a state handler which has the gl lock held and a context for the thread */
2116 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2117 the form (a1 <operation> a2). However, some of the more complex operations
2118 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2119 in a third parameter called a0. Therefore these are operations of the form
2120 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2122 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2123 functions below, expect their syntax to differ slightly to those listed in the
2124 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2125 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2127 if (isAlpha)
2129 comb_target = GL_COMBINE_ALPHA;
2130 src0_target = GL_SOURCE0_ALPHA;
2131 src1_target = GL_SOURCE1_ALPHA;
2132 src2_target = GL_SOURCE2_ALPHA;
2133 opr0_target = GL_OPERAND0_ALPHA;
2134 opr1_target = GL_OPERAND1_ALPHA;
2135 opr2_target = GL_OPERAND2_ALPHA;
2136 scal_target = GL_ALPHA_SCALE;
2138 else
2140 comb_target = GL_COMBINE_RGB;
2141 src0_target = GL_SOURCE0_RGB;
2142 src1_target = GL_SOURCE1_RGB;
2143 src2_target = GL_SOURCE2_RGB;
2144 opr0_target = GL_OPERAND0_RGB;
2145 opr1_target = GL_OPERAND1_RGB;
2146 opr2_target = GL_OPERAND2_RGB;
2147 scal_target = GL_RGB_SCALE;
2150 /* If a texture stage references an invalid texture unit the stage just
2151 * passes through the result from the previous stage */
2152 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2154 arg1 = WINED3DTA_CURRENT;
2155 op = WINED3D_TOP_SELECT_ARG1;
2158 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2160 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2161 } else {
2162 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2164 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2165 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2167 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2169 Handled = TRUE; /* Assume will be handled */
2171 /* Other texture operations require special extensions: */
2172 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2174 if (isAlpha) {
2175 opr = GL_SRC_ALPHA;
2176 invopr = GL_ONE_MINUS_SRC_ALPHA;
2177 src3_target = GL_SOURCE3_ALPHA_NV;
2178 opr3_target = GL_OPERAND3_ALPHA_NV;
2179 } else {
2180 opr = GL_SRC_COLOR;
2181 invopr = GL_ONE_MINUS_SRC_COLOR;
2182 src3_target = GL_SOURCE3_RGB_NV;
2183 opr3_target = GL_OPERAND3_RGB_NV;
2185 switch (op)
2187 case WINED3D_TOP_DISABLE: /* Only for alpha */
2188 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2189 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2190 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2191 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2192 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2193 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2194 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2195 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2196 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2197 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2198 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2199 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2200 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2201 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2202 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2203 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2204 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2205 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2206 break;
2208 case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
2209 case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
2210 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2211 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2212 if (op == WINED3D_TOP_SELECT_ARG1)
2214 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2215 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2216 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2217 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2219 else
2221 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2222 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2223 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2224 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2226 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2227 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2228 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2229 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2230 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2231 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2232 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2233 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2234 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2235 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2236 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2237 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2238 break;
2240 case WINED3D_TOP_MODULATE:
2241 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2242 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2243 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2244 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2245 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2246 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2247 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2248 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2249 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2250 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2251 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2252 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2253 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2254 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2255 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2256 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2257 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2258 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2259 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2260 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2261 break;
2262 case WINED3D_TOP_MODULATE_2X:
2263 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2264 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2265 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2266 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2267 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2268 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2269 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2270 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2271 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2272 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2273 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2274 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2275 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2276 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2277 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2278 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2279 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2280 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2281 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2282 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2283 break;
2284 case WINED3D_TOP_MODULATE_4X:
2285 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2286 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2287 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2288 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2289 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2290 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2291 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2292 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2293 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2294 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2295 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2296 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2297 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2298 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2299 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2300 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2301 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2302 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2303 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2304 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2305 break;
2307 case WINED3D_TOP_ADD:
2308 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2309 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2310 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2311 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2312 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2313 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2314 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2315 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2316 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2317 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2318 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2319 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2320 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2321 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2322 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2323 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2324 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2325 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2326 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2327 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2328 break;
2330 case WINED3D_TOP_ADD_SIGNED:
2331 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2332 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2333 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2334 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2335 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2336 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2337 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2338 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2339 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2340 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2341 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2342 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2343 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2344 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2345 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2346 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2347 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2348 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2349 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2350 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2351 break;
2353 case WINED3D_TOP_ADD_SIGNED_2X:
2354 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2355 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2356 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2357 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2358 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2359 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2360 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2361 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2362 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2363 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2364 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2365 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2366 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2367 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2368 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2369 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2370 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2371 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2372 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2373 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2374 break;
2376 case WINED3D_TOP_ADD_SMOOTH:
2377 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2378 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2379 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2380 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2381 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2382 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2383 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2384 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2385 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2386 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2387 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2388 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2389 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2390 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2391 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2392 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2393 switch (opr1) {
2394 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2395 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2396 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2397 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2399 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2400 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2401 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2402 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2403 break;
2405 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2406 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2407 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2408 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2409 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2410 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2411 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2412 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
2413 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
2414 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2415 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2416 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2417 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2418 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2419 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2420 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
2421 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
2422 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2423 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2424 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2425 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2426 break;
2427 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2428 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2429 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2430 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2431 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2432 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2433 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2434 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2435 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2436 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2437 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2438 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2439 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2440 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2441 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2442 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2443 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2444 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2445 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2446 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2447 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2448 break;
2449 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2450 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2451 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2452 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2453 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2454 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2455 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2456 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
2457 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
2458 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2459 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2460 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2461 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2462 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2463 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2464 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
2465 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
2466 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2467 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2468 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2469 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2470 break;
2471 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2472 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2473 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2474 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2475 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2476 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2477 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2478 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2479 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2480 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2481 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2482 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2483 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2484 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2485 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2486 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2487 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2488 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2489 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2490 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2491 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2492 break;
2493 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2494 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2495 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2496 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2497 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2498 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2499 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2500 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2501 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2502 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2503 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2504 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2505 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2506 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2507 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2508 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2509 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2510 switch (opr) {
2511 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2512 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2514 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2515 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2516 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2517 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2518 break;
2519 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2520 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2521 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2522 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2523 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2524 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2525 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2526 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2527 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2528 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2529 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2530 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2531 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2532 switch (opr1) {
2533 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2534 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2536 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2537 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2538 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2539 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2540 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2541 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2542 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2543 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2544 break;
2545 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2546 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2547 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2548 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2549 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2550 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2551 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2552 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2553 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2554 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2555 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2556 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2557 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2558 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2559 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2560 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2561 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2562 switch (opr1) {
2563 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2564 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2565 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2566 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2568 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2569 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2570 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2571 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2572 break;
2573 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2574 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2575 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2576 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2577 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2578 switch (opr1) {
2579 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2580 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2581 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2582 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2584 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2585 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2586 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2587 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2588 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2589 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2590 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2591 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2592 switch (opr1) {
2593 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2594 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2596 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2597 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2598 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2599 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2600 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2601 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2602 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2603 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2604 break;
2605 case WINED3D_TOP_MULTIPLY_ADD:
2606 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2607 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2608 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2609 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2610 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2611 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2612 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2613 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2614 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2615 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2616 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2617 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2618 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2619 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2620 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2621 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2622 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2623 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2624 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2625 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2626 break;
2628 case WINED3D_TOP_BUMPENVMAP:
2629 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
2630 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2631 Handled = FALSE;
2632 break;
2634 default:
2635 Handled = FALSE;
2637 if (Handled)
2639 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2640 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2642 return;
2644 } /* GL_NV_texture_env_combine4 */
2646 Handled = TRUE; /* Again, assume handled */
2647 switch (op) {
2648 case WINED3D_TOP_DISABLE: /* Only for alpha */
2649 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2650 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2651 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2652 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2653 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2654 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
2655 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2656 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2657 break;
2658 case WINED3D_TOP_SELECT_ARG1:
2659 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2660 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2661 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2662 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2663 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2664 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2665 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2666 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2667 break;
2668 case WINED3D_TOP_SELECT_ARG2:
2669 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2670 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2671 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2672 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2673 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2674 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2675 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2676 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2677 break;
2678 case WINED3D_TOP_MODULATE:
2679 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2680 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2681 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2682 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2683 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2684 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2685 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2686 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2687 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2688 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2689 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2690 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2691 break;
2692 case WINED3D_TOP_MODULATE_2X:
2693 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2694 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2695 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2696 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2697 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2698 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2699 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2700 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2701 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2702 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2703 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2704 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2705 break;
2706 case WINED3D_TOP_MODULATE_4X:
2707 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2708 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2709 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2710 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2711 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2712 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2713 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2714 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2715 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2716 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2717 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2718 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2719 break;
2720 case WINED3D_TOP_ADD:
2721 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2722 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2723 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2724 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2725 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2726 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2727 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2728 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2729 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2730 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2731 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2732 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2733 break;
2734 case WINED3D_TOP_ADD_SIGNED:
2735 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2736 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2737 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2738 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2739 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2740 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2741 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2742 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2743 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2744 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2745 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2746 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2747 break;
2748 case WINED3D_TOP_ADD_SIGNED_2X:
2749 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2750 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2751 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2752 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2753 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2754 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2755 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2756 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2757 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2758 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2759 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2760 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2761 break;
2762 case WINED3D_TOP_SUBTRACT:
2763 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2765 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2766 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2767 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2768 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2769 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2770 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2771 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2772 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2773 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2774 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2775 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2776 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2777 } else {
2778 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2780 break;
2782 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2783 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2784 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2785 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2786 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2787 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2788 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2789 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2790 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2791 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2792 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2793 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
2794 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2795 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2796 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2797 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2798 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2799 break;
2800 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2801 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2802 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2803 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2804 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2805 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2806 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2807 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2808 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2809 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2810 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2811 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2812 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2813 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2814 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2815 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2816 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2817 break;
2818 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2819 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2820 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2821 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2822 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2823 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2824 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2825 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2826 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2827 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2828 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2829 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
2830 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2831 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2832 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2833 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2834 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2835 break;
2836 case WINED3D_TOP_BLEND_CURRENT_ALPHA:
2837 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2838 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2839 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2840 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2841 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2842 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2843 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2844 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2845 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2846 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2847 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
2848 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2849 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2850 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2851 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2852 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2853 break;
2854 case WINED3D_TOP_DOTPRODUCT3:
2855 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2857 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2858 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2860 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2862 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2863 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2864 } else {
2865 FIXME("This version of opengl does not support GL_DOT3\n");
2867 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2868 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2869 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2870 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2871 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2872 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2873 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2874 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2875 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2876 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2877 break;
2878 case WINED3D_TOP_LERP:
2879 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2880 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2881 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2882 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2883 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2884 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2885 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2886 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2887 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2888 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2889 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2890 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2891 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2892 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2893 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2894 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2895 break;
2896 case WINED3D_TOP_ADD_SMOOTH:
2897 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2899 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2900 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2901 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2902 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2903 switch (opr1) {
2904 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2905 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2906 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2907 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2909 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2910 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2911 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2912 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2913 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2914 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2915 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2916 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2917 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2918 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2919 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2920 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2921 } else
2922 Handled = FALSE;
2923 break;
2924 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2925 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2927 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2928 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2929 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2930 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2931 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2932 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2933 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2934 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2935 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2936 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2937 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2938 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2939 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2940 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2941 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2942 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2943 } else
2944 Handled = FALSE;
2945 break;
2946 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2947 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2949 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2950 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2951 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2952 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2953 switch (opr1) {
2954 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2955 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2956 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2957 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2959 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2960 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2961 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2962 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2963 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2964 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2965 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2966 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2967 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2968 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2969 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2970 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2971 } else
2972 Handled = FALSE;
2973 break;
2974 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2975 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2977 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2978 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2979 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2980 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2981 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2982 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2983 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2984 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2985 switch (opr1) {
2986 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2987 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2988 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2989 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2991 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
2992 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
2993 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2994 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2995 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2996 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2997 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2998 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2999 } else
3000 Handled = FALSE;
3001 break;
3002 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3003 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3005 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3006 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3007 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3008 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3009 switch (opr1) {
3010 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3011 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3012 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3013 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3015 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3016 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3017 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3018 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3019 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
3020 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
3021 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3022 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3023 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3024 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3025 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3026 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3027 } else
3028 Handled = FALSE;
3029 break;
3030 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3031 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3033 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3034 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3035 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3036 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3037 switch (opr1) {
3038 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
3039 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
3040 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3041 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3043 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3044 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3045 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3046 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3047 switch (opr1) {
3048 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3049 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3050 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3051 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3053 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
3054 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
3055 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3056 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3057 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3058 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3059 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3060 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3061 } else
3062 Handled = FALSE;
3063 break;
3064 case WINED3D_TOP_MULTIPLY_ADD:
3065 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3067 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3068 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3069 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3070 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3071 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3072 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3073 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3074 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3075 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3076 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3077 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3078 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3079 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3080 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3081 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3082 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3083 } else
3084 Handled = FALSE;
3085 break;
3086 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3087 case WINED3D_TOP_BUMPENVMAP:
3088 if (gl_info->supported[NV_TEXTURE_SHADER2])
3090 /* Technically texture shader support without register combiners is possible, but not expected to occur
3091 * on real world cards, so for now a fixme should be enough
3093 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3095 Handled = FALSE;
3096 break;
3098 default:
3099 Handled = FALSE;
3102 if (Handled) {
3103 BOOL combineOK = TRUE;
3104 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3106 DWORD op2;
3108 if (isAlpha)
3109 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3110 else
3111 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3113 /* Note: If COMBINE4 in effect can't go back to combine! */
3114 switch (op2)
3116 case WINED3D_TOP_ADD_SMOOTH:
3117 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3118 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3119 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3120 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3121 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3122 case WINED3D_TOP_MULTIPLY_ADD:
3123 /* Ignore those implemented in both cases */
3124 switch (op)
3126 case WINED3D_TOP_SELECT_ARG1:
3127 case WINED3D_TOP_SELECT_ARG2:
3128 combineOK = FALSE;
3129 Handled = FALSE;
3130 break;
3131 default:
3132 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3133 return;
3138 if (combineOK)
3140 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3141 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3143 return;
3147 /* After all the extensions, if still unhandled, report fixme */
3148 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3152 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3154 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3155 const struct wined3d_device *device = context->swapchain->device;
3156 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3157 DWORD mapped_stage = device->texUnitMap[stage];
3158 const struct wined3d_gl_info *gl_info = context->gl_info;
3160 TRACE("Setting color op for stage %d\n", stage);
3162 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3163 if (use_ps(state)) return;
3165 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3167 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3169 if (tex_used && mapped_stage >= gl_info->limits.textures)
3171 FIXME("Attempt to enable unsupported stage!\n");
3172 return;
3174 context_active_texture(context, gl_info, mapped_stage);
3177 if (stage >= state->lowest_disabled_stage)
3179 TRACE("Stage disabled\n");
3180 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3182 /* Disable everything here */
3183 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3184 checkGLcall("glDisable(GL_TEXTURE_2D)");
3185 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3186 checkGLcall("glDisable(GL_TEXTURE_3D)");
3187 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3189 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3190 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3192 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3194 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3195 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3198 /* All done */
3199 return;
3202 /* The sampler will also activate the correct texture dimensions, so no
3203 * need to do it here if the sampler for this stage is dirty. */
3204 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3205 texture_activate_dimensions(state->textures[stage], gl_info);
3207 set_tex_op(gl_info, state, FALSE, stage,
3208 state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3209 state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3210 state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3211 state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3214 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3216 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3217 const struct wined3d_device *device = context->swapchain->device;
3218 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3219 DWORD mapped_stage = device->texUnitMap[stage];
3220 const struct wined3d_gl_info *gl_info = context->gl_info;
3221 DWORD op, arg1, arg2, arg0;
3223 TRACE("Setting alpha op for stage %d\n", stage);
3224 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3225 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3227 if (tex_used && mapped_stage >= gl_info->limits.textures)
3229 FIXME("Attempt to enable unsupported stage!\n");
3230 return;
3232 context_active_texture(context, gl_info, mapped_stage);
3235 op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3236 arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3237 arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3238 arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3240 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3242 struct wined3d_texture *texture = state->textures[0];
3243 GLenum texture_dimensions = texture->target;
3245 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3247 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3249 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_size)
3251 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3252 * properly. On the other hand applications can still use texture combiners apparently. This code
3253 * takes care that apps cannot remove the texture's alpha channel entirely.
3255 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3256 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3257 * and alpha component of diffuse color to draw things like translucent text and perform other
3258 * blending effects.
3260 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3261 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3262 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3263 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3264 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3265 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3266 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3267 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3268 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3269 * alpha.
3271 * What to do with multitexturing? So far no app has been found that uses color keying with
3272 * multitexturing */
3273 if (op == WINED3D_TOP_DISABLE)
3275 arg1 = WINED3DTA_TEXTURE;
3276 op = WINED3D_TOP_SELECT_ARG1;
3278 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3280 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3282 arg2 = WINED3DTA_TEXTURE;
3283 op = WINED3D_TOP_MODULATE;
3285 else arg1 = WINED3DTA_TEXTURE;
3287 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3289 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3291 arg1 = WINED3DTA_TEXTURE;
3292 op = WINED3D_TOP_MODULATE;
3294 else arg2 = WINED3DTA_TEXTURE;
3300 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3301 * this if block here, and the other code(color keying, texture unit selection) are the same
3303 TRACE("Setting alpha op for stage %d\n", stage);
3304 if (gl_info->supported[NV_REGISTER_COMBINERS])
3306 set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3307 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3309 else
3311 set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3315 static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3317 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3318 const struct wined3d_device *device = context->swapchain->device;
3319 const struct wined3d_gl_info *gl_info = context->gl_info;
3320 DWORD mapped_stage = device->texUnitMap[texUnit];
3321 BOOL generated;
3322 int coordIdx;
3324 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3325 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3327 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3328 return;
3331 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3332 if (mapped_stage >= gl_info->limits.textures) return;
3334 context_active_texture(context, gl_info, mapped_stage);
3335 generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3336 coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3338 set_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3339 state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3340 generated, context->last_was_rhw,
3341 device->stream_info.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3342 ? device->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3343 : WINED3DFMT_UNKNOWN,
3344 device->shader_backend->shader_has_ffp_proj_control(device->shader_priv));
3346 /* The sampler applying function calls us if this changes */
3347 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3349 if(generated) {
3350 FIXME("Non-power2 texture being used with generated texture coords\n");
3352 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3353 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3354 if (!use_ps(state))
3356 TRACE("Non power two matrix multiply fixup\n");
3357 gl_info->gl_ops.gl.p_glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3362 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3364 unsigned int texture_idx;
3366 for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3368 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3369 gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3373 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3374 GLuint *curVBO, const struct wined3d_state *state)
3376 const struct wined3d_device *device = context->swapchain->device;
3377 const struct wined3d_gl_info *gl_info = context->gl_info;
3378 unsigned int mapped_stage = 0;
3379 unsigned int textureNo = 0;
3381 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3383 int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3385 mapped_stage = device->texUnitMap[textureNo];
3386 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3388 if (mapped_stage >= gl_info->limits.texture_coords)
3390 FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3391 continue;
3394 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3396 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3398 TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3399 textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3401 if (*curVBO != e->data.buffer_object)
3403 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3404 checkGLcall("glBindBufferARB");
3405 *curVBO = e->data.buffer_object;
3408 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3409 checkGLcall("glClientActiveTextureARB");
3411 /* The coords to supply depend completely on the fvf / vertex shader */
3412 gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3413 e->data.addr + state->load_base_vertex_index * e->stride);
3414 gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3416 else
3418 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3421 if (gl_info->supported[NV_REGISTER_COMBINERS])
3423 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3424 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3426 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3430 checkGLcall("loadTexCoords");
3433 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3435 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3436 const struct wined3d_device *device = context->swapchain->device;
3437 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3438 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3439 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3440 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3441 const struct wined3d_gl_info *gl_info = context->gl_info;
3442 DWORD mapped_stage = device->texUnitMap[stage];
3444 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3446 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3447 return;
3450 if (mapped_stage >= gl_info->limits.fragment_samplers)
3452 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3453 return;
3455 context_active_texture(context, gl_info, mapped_stage);
3457 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3459 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3460 * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3461 * means use the vertex position (camera-space) as the input texture coordinates
3462 * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3463 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3464 * to the TEXCOORDINDEX value
3466 switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3468 case WINED3DTSS_TCI_PASSTHRU:
3469 /* Use the specified texture coordinates contained within the
3470 * vertex format. This value resolves to zero. */
3471 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3472 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3473 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3474 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3475 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3476 break;
3478 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3479 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3480 * as the input texture coordinates for this stage's texture transformation. This
3481 * equates roughly to EYE_LINEAR */
3483 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3484 gl_info->gl_ops.gl.p_glPushMatrix();
3485 gl_info->gl_ops.gl.p_glLoadIdentity();
3486 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3487 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3488 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3489 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3490 gl_info->gl_ops.gl.p_glPopMatrix();
3491 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3493 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3494 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3495 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3496 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3498 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3499 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3500 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3501 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3503 break;
3505 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3506 /* Note that NV_TEXGEN_REFLECTION support is implied when
3507 * ARB_TEXTURE_CUBE_MAP is supported */
3508 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3510 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3511 break;
3514 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3515 gl_info->gl_ops.gl.p_glPushMatrix();
3516 gl_info->gl_ops.gl.p_glLoadIdentity();
3517 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3518 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3519 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3520 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3521 gl_info->gl_ops.gl.p_glPopMatrix();
3522 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3524 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3525 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3526 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3527 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3529 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3530 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3531 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3532 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3534 break;
3536 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3537 /* Note that NV_TEXGEN_REFLECTION support is implied when
3538 * ARB_TEXTURE_CUBE_MAP is supported */
3539 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3541 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3542 break;
3545 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3546 gl_info->gl_ops.gl.p_glPushMatrix();
3547 gl_info->gl_ops.gl.p_glLoadIdentity();
3548 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3549 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3550 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3551 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3552 gl_info->gl_ops.gl.p_glPopMatrix();
3553 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3555 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3556 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3557 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3558 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3560 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3561 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3562 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3563 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3565 break;
3567 case WINED3DTSS_TCI_SPHEREMAP:
3568 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3569 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3570 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3572 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3573 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3574 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3575 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3577 break;
3579 default:
3580 FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3581 state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3582 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3583 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3584 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3585 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3586 checkGLcall("Disable texgen.");
3588 break;
3591 /* Update the texture matrix. */
3592 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3593 transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3595 if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3597 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3598 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3599 * and do all the things linked to it
3600 * TODO: Tidy that up to reload only the arrays of the changed unit
3602 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3604 unload_tex_coords(gl_info);
3605 load_tex_coords(context, &device->stream_info, &curVBO, state);
3609 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3611 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3612 const struct wined3d_shader *ps = state->pixel_shader;
3614 /* The pixel shader has to know the luminance scale. Do a constants update. */
3615 if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3616 context->load_constants = 1;
3619 static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3621 const DWORD sampler = state_id - STATE_SAMPLER(0);
3622 const struct wined3d_texture *texture = state->textures[sampler];
3624 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3626 if(!texture) return;
3627 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3628 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3629 * scaling is reapplied or removed, the texture matrix has to be reapplied
3631 * The mapped stage is already active because the sampler() function below, which is part of the
3632 * misc pipeline
3634 if (sampler < MAX_TEXTURES)
3636 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3638 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3640 const struct wined3d_device *device = context->swapchain->device;
3642 if (texIsPow2)
3643 context->lastWasPow2Texture |= 1 << sampler;
3644 else
3645 context->lastWasPow2Texture &= ~(1 << sampler);
3647 transform_texture(context, state,
3648 STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3653 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3655 const struct wined3d_device *device = context->swapchain->device;
3656 DWORD sampler = state_id - STATE_SAMPLER(0);
3657 DWORD mapped_stage = device->texUnitMap[sampler];
3658 const struct wined3d_gl_info *gl_info = context->gl_info;
3659 union {
3660 float f;
3661 DWORD d;
3662 } tmpvalue;
3664 TRACE("Sampler: %d\n", sampler);
3665 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3666 * only has to bind textures and set the per texture states
3669 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3671 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3672 return;
3675 if (mapped_stage >= gl_info->limits.combined_samplers)
3677 return;
3679 context_active_texture(context, gl_info, mapped_stage);
3681 if (state->textures[sampler])
3683 struct wined3d_texture *texture = state->textures[sampler];
3684 BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3686 texture->texture_ops->texture_bind(texture, context, srgb);
3687 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3689 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3691 tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3692 gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3693 GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f);
3694 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3697 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3699 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3701 /* If color keying is enabled update the alpha test, it
3702 * depends on the existence of a color key in stage 0. */
3703 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3707 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3708 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3709 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3711 else
3713 if (sampler < state->lowest_disabled_stage)
3715 /* TODO: What should I do with pixel shaders here ??? */
3716 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3718 /* If color keying is enabled update the alpha test, it
3719 * depends on the existence of a color key in stage 0. */
3720 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3722 } /* Otherwise tex_colorop disables the stage */
3723 context_bind_texture(context, GL_NONE, 0);
3727 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3729 unsigned int i;
3731 if (use_ps(state))
3733 if (!context->last_was_pshader)
3735 /* Former draw without a pixel shader, some samplers may be
3736 * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3737 * make sure to enable them. */
3738 for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3740 if (!isStateDirty(context, STATE_SAMPLER(i)))
3741 sampler(context, state, STATE_SAMPLER(i));
3743 context->last_was_pshader = TRUE;
3745 else
3747 /* Otherwise all samplers were activated by the code above in
3748 * earlier draws, or by sampler() if a different texture was
3749 * bound. I don't have to do anything. */
3752 else
3754 /* Disabled the pixel shader - color ops weren't applied while it was
3755 * enabled, so re-apply them. */
3756 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3758 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3759 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3761 context->last_was_pshader = FALSE;
3764 context->select_shader = 1;
3765 context->load_constants = 1;
3768 static void state_geometry_shader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3770 context->select_shader = 1;
3773 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3775 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3776 const struct wined3d_shader *ps = state->pixel_shader;
3778 /* The pixel shader has to know the bump env matrix. Do a constants update. */
3779 if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3780 context->load_constants = 1;
3783 static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3785 const struct wined3d_gl_info *gl_info = context->gl_info;
3787 /* This function is called by transform_view below if the view matrix was changed too
3789 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3790 * does not always update the world matrix, only on a switch between transformed
3791 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3792 * draw, but that should be rather rare and cheaper in total.
3794 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3795 checkGLcall("glMatrixMode");
3797 if (context->last_was_rhw)
3799 gl_info->gl_ops.gl.p_glLoadIdentity();
3800 checkGLcall("glLoadIdentity()");
3802 else
3804 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3805 checkGLcall("glLoadMatrixf");
3806 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3807 checkGLcall("glMultMatrixf");
3811 static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3813 const struct wined3d_gl_info *gl_info = context->gl_info;
3814 UINT index = state_id - STATE_CLIPPLANE(0);
3815 GLdouble plane[4];
3817 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.clipplanes)
3818 return;
3820 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3821 gl_info->gl_ops.gl.p_glPushMatrix();
3823 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3824 if (!use_vs(state))
3825 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3826 else
3827 /* With vertex shaders, clip planes are not transformed in Direct3D,
3828 * while in OpenGL they are still transformed by the model view matix. */
3829 gl_info->gl_ops.gl.p_glLoadIdentity();
3831 plane[0] = state->clip_planes[index].x;
3832 plane[1] = state->clip_planes[index].y;
3833 plane[2] = state->clip_planes[index].z;
3834 plane[3] = state->clip_planes[index].w;
3836 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3837 plane[0], plane[1], plane[2], plane[3]);
3838 gl_info->gl_ops.gl.p_glClipPlane(GL_CLIP_PLANE0 + index, plane);
3839 checkGLcall("glClipPlane");
3841 gl_info->gl_ops.gl.p_glPopMatrix();
3844 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3846 UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3847 const struct wined3d_gl_info *gl_info = context->gl_info;
3848 GLenum glMat;
3850 TRACE("Setting world matrix %d\n", matrix);
3852 if (matrix >= gl_info->limits.blends)
3854 WARN("Unsupported blend matrix set\n");
3855 return;
3858 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3859 return;
3861 /* GL_MODELVIEW0_ARB: 0x1700
3862 * GL_MODELVIEW1_ARB: 0x850a
3863 * GL_MODELVIEW2_ARB: 0x8722
3864 * GL_MODELVIEW3_ARB: 0x8723
3865 * etc
3866 * GL_MODELVIEW31_ARB: 0x873f
3868 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3869 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3871 gl_info->gl_ops.gl.p_glMatrixMode(glMat);
3872 checkGLcall("glMatrixMode(glMat)");
3874 /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3875 * matrices while gl uses only 2. To avoid weighting the view matrix
3876 * incorrectly it has to be multiplied into every GL modelview matrix. */
3877 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3878 checkGLcall("glLoadMatrixf");
3879 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3880 checkGLcall("glMultMatrixf");
3883 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3885 enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3886 static unsigned int once;
3888 if (f == WINED3D_VBF_DISABLE)
3889 return;
3891 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3892 else WARN("Vertex blend flags %#x not supported.\n", f);
3895 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3897 enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3898 struct wined3d_device *device = context->swapchain->device;
3899 const struct wined3d_gl_info *gl_info = context->gl_info;
3900 static unsigned int once;
3902 switch (val)
3904 case WINED3D_VBF_1WEIGHTS:
3905 case WINED3D_VBF_2WEIGHTS:
3906 case WINED3D_VBF_3WEIGHTS:
3907 gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB);
3908 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3910 /* D3D adds one more matrix which has weight (1 - sum(weights)).
3911 * This is enabled at context creation with enabling
3912 * GL_WEIGHT_SUM_UNITY_ARB. */
3913 GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3915 if (!device->vertexBlendUsed)
3917 unsigned int i;
3918 for (i = 1; i < gl_info->limits.blends; ++i)
3920 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3921 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3923 device->vertexBlendUsed = TRUE;
3925 break;
3927 case WINED3D_VBF_TWEENING:
3928 case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3929 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3930 else WARN("Vertex blend flags %#x not supported.\n", val);
3931 /* Fall through. */
3932 case WINED3D_VBF_DISABLE:
3933 gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB);
3934 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3935 break;
3939 static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3941 const struct wined3d_gl_info *gl_info = context->gl_info;
3942 const struct wined3d_light_info *light = NULL;
3943 unsigned int k;
3945 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3946 * NOTE: We have to reset the positions even if the light/plane is not currently
3947 * enabled, since the call to enable it will not reset the position.
3948 * NOTE2: Apparently texture transforms do NOT need reapplying
3951 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3952 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3953 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3954 checkGLcall("glLoadMatrixf(...)");
3956 /* Reset lights. TODO: Call light apply func */
3957 for (k = 0; k < gl_info->limits.lights; ++k)
3959 if (!(light = state->lights[k]))
3960 continue;
3961 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3962 checkGLcall("glLightfv posn");
3963 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
3964 checkGLcall("glLightfv dirn");
3967 /* Reset Clipping Planes */
3968 for (k = 0; k < gl_info->limits.clipplanes; ++k)
3970 if (!isStateDirty(context, STATE_CLIPPLANE(k)))
3971 clipplane(context, state, STATE_CLIPPLANE(k));
3974 if (context->last_was_rhw)
3976 gl_info->gl_ops.gl.p_glLoadIdentity();
3977 checkGLcall("glLoadIdentity()");
3978 /* No need to update the world matrix, the identity is fine */
3979 return;
3982 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
3983 * No need to do it here if the state is scheduled for update. */
3984 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
3985 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
3987 /* Avoid looping over a number of matrices if the app never used the functionality */
3988 if (context->swapchain->device->vertexBlendUsed)
3990 for (k = 1; k < gl_info->limits.blends; ++k)
3992 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
3993 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
3998 static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4000 const struct wined3d_gl_info *gl_info = context->gl_info;
4002 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
4003 checkGLcall("glMatrixMode(GL_PROJECTION)");
4005 /* There are a couple of additional things we have to take into account
4006 * here besides the projection transformation itself:
4007 * - We need to flip along the y-axis in case of offscreen rendering.
4008 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
4009 * - D3D coordinates refer to pixel centers while GL coordinates refer
4010 * to pixel corners.
4011 * - D3D has a top-left filling convention. We need to maintain this
4012 * even after the y-flip mentioned above.
4013 * In order to handle the last two points, we translate by
4014 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
4015 * translating slightly less than half a pixel. We want the difference to
4016 * be large enough that it doesn't get lost due to rounding inside the
4017 * driver, but small enough to prevent it from interfering with any
4018 * anti-aliasing. */
4020 if (context->last_was_rhw)
4022 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
4023 double x = state->viewport.x;
4024 double y = state->viewport.y;
4025 double w = state->viewport.width;
4026 double h = state->viewport.height;
4027 double x_scale = 2.0 / w;
4028 double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
4029 double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
4030 double y_offset = context->render_offscreen
4031 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
4032 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
4033 const GLdouble projection[] =
4035 x_scale, 0.0, 0.0, 0.0,
4036 0.0, y_scale, 0.0, 0.0,
4037 0.0, 0.0, 2.0, 0.0,
4038 x_offset, y_offset, -1.0, 1.0,
4041 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4042 checkGLcall("glLoadMatrixd");
4044 else
4046 double y_scale = context->render_offscreen ? -1.0 : 1.0;
4047 double x_offset = (63.0 / 64.0) / state->viewport.width;
4048 double y_offset = context->render_offscreen
4049 ? (63.0 / 64.0) / state->viewport.height
4050 : -(63.0 / 64.0) / state->viewport.height;
4051 const GLdouble projection[] =
4053 1.0, 0.0, 0.0, 0.0,
4054 0.0, y_scale, 0.0, 0.0,
4055 0.0, 0.0, 2.0, 0.0,
4056 x_offset, y_offset, -1.0, 1.0,
4059 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4060 checkGLcall("glLoadMatrixd");
4062 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4063 checkGLcall("glLoadMatrixf");
4067 /* This should match any arrays loaded in load_vertex_data.
4068 * TODO: Only load / unload arrays if we have to. */
4069 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4071 gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
4072 gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
4073 gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
4074 if (gl_info->supported[EXT_SECONDARY_COLOR])
4075 gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4076 if (gl_info->supported[ARB_VERTEX_BLEND])
4077 gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4078 unload_tex_coords(gl_info);
4081 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4083 const struct wined3d_gl_info *gl_info = context->gl_info;
4085 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4086 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4087 if (gl_info->supported[ARB_INSTANCED_ARRAYS])
4088 GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
4090 context->numbered_array_mask &= ~(1 << i);
4093 /* This should match any arrays loaded in loadNumberedArrays
4094 * TODO: Only load / unload arrays if we have to. */
4095 static void unload_numbered_arrays(struct wined3d_context *context)
4097 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4098 int i;
4100 for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4101 unload_numbered_array(context, i);
4105 static void load_numbered_arrays(struct wined3d_context *context,
4106 const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4108 struct wined3d_device *device = context->swapchain->device;
4109 const struct wined3d_gl_info *gl_info = context->gl_info;
4110 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4111 int i;
4113 /* Default to no instancing */
4114 device->instance_count = 0;
4116 for (i = 0; i < MAX_ATTRIBS; i++)
4118 const struct wined3d_stream_state *stream;
4120 if (!(stream_info->use_map & (1 << i)))
4122 if (context->numbered_array_mask & (1 << i))
4123 unload_numbered_array(context, i);
4124 if (state->vertex_shader->reg_maps.input_registers & (1 << i))
4125 GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
4126 continue;
4129 stream = &state->streams[stream_info->elements[i].stream_idx];
4131 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4133 if (!device->instance_count)
4134 device->instance_count = state->streams[0].frequency ? state->streams[0].frequency : 1;
4136 if (!gl_info->supported[ARB_INSTANCED_ARRAYS])
4138 /* Unload instanced arrays, they will be loaded using
4139 * immediate mode instead. */
4140 if (context->numbered_array_mask & (1 << i))
4141 unload_numbered_array(context, i);
4142 continue;
4145 GL_EXTCALL(glVertexAttribDivisorARB(i, 1));
4147 else if (gl_info->supported[ARB_INSTANCED_ARRAYS])
4149 GL_EXTCALL(glVertexAttribDivisorARB(i, 0));
4152 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4154 if (stream_info->elements[i].stride)
4156 if (curVBO != stream_info->elements[i].data.buffer_object)
4158 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4159 checkGLcall("glBindBufferARB");
4160 curVBO = stream_info->elements[i].data.buffer_object;
4162 /* Use the VBO to find out if a vertex buffer exists, not the vb
4163 * pointer. vb can point to a user pointer data blob. In that case
4164 * curVBO will be 0. If there is a vertex buffer but no vbo we
4165 * won't be load converted attributes anyway. */
4166 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4167 stream_info->elements[i].format->gl_vtx_type,
4168 stream_info->elements[i].format->gl_normalized,
4169 stream_info->elements[i].stride, stream_info->elements[i].data.addr
4170 + state->load_base_vertex_index * stream_info->elements[i].stride));
4172 if (!(context->numbered_array_mask & (1 << i)))
4174 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4175 context->numbered_array_mask |= (1 << i);
4178 else
4180 /* Stride = 0 means always the same values.
4181 * glVertexAttribPointerARB doesn't do that. Instead disable the
4182 * pointer and set up the attribute statically. But we have to
4183 * figure out the system memory address. */
4184 const BYTE *ptr = stream_info->elements[i].data.addr;
4185 if (stream_info->elements[i].data.buffer_object)
4187 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4190 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4192 switch (stream_info->elements[i].format->id)
4194 case WINED3DFMT_R32_FLOAT:
4195 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4196 break;
4197 case WINED3DFMT_R32G32_FLOAT:
4198 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4199 break;
4200 case WINED3DFMT_R32G32B32_FLOAT:
4201 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4202 break;
4203 case WINED3DFMT_R32G32B32A32_FLOAT:
4204 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4205 break;
4207 case WINED3DFMT_R8G8B8A8_UINT:
4208 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4209 break;
4210 case WINED3DFMT_B8G8R8A8_UNORM:
4211 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4213 const DWORD *src = (const DWORD *)ptr;
4214 DWORD c = *src & 0xff00ff00;
4215 c |= (*src & 0xff0000) >> 16;
4216 c |= (*src & 0xff) << 16;
4217 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4218 break;
4220 /* else fallthrough */
4221 case WINED3DFMT_R8G8B8A8_UNORM:
4222 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4223 break;
4225 case WINED3DFMT_R16G16_SINT:
4226 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4227 break;
4228 case WINED3DFMT_R16G16B16A16_SINT:
4229 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4230 break;
4232 case WINED3DFMT_R16G16_SNORM:
4234 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4235 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4236 break;
4238 case WINED3DFMT_R16G16_UNORM:
4240 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4241 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4242 break;
4244 case WINED3DFMT_R16G16B16A16_SNORM:
4245 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4246 break;
4247 case WINED3DFMT_R16G16B16A16_UNORM:
4248 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4249 break;
4251 case WINED3DFMT_R10G10B10A2_UINT:
4252 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4253 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4254 break;
4255 case WINED3DFMT_R10G10B10A2_SNORM:
4256 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4257 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4258 break;
4260 case WINED3DFMT_R16G16_FLOAT:
4261 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4262 * byte float according to the IEEE standard
4264 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4265 break;
4266 case WINED3DFMT_R16G16B16A16_FLOAT:
4267 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4268 break;
4270 default:
4271 ERR("Unexpected declaration in stride 0 attributes\n");
4272 break;
4277 checkGLcall("Loading numbered arrays");
4280 static void load_vertex_data(const struct wined3d_context *context,
4281 const struct wined3d_stream_info *si, const struct wined3d_state *state)
4283 struct wined3d_device *device = context->swapchain->device;
4284 const struct wined3d_gl_info *gl_info = context->gl_info;
4285 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4286 const struct wined3d_stream_info_element *e;
4288 TRACE("Using fast vertex array code\n");
4290 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4291 device->instance_count = 0;
4293 /* Blend Data ---------------------------------------------- */
4294 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4295 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4297 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4299 if (gl_info->supported[ARB_VERTEX_BLEND])
4301 TRACE("Blend %u %p %u\n", e->format->component_count,
4302 e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4304 gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4305 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4307 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4309 if (curVBO != e->data.buffer_object)
4311 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4312 checkGLcall("glBindBufferARB");
4313 curVBO = e->data.buffer_object;
4316 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4317 e->format->gl_vtx_format,
4318 e->format->gl_vtx_type,
4319 e->stride,
4320 e->data.addr + state->load_base_vertex_index * e->stride);
4321 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4322 e->data.addr + state->load_base_vertex_index * e->stride));
4324 checkGLcall("glWeightPointerARB");
4326 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4328 static BOOL warned;
4329 if (!warned)
4331 FIXME("blendMatrixIndices support\n");
4332 warned = TRUE;
4335 } else {
4336 /* TODO: support blends in drawStridedSlow
4337 * No need to write a FIXME here, this is done after the general vertex decl decoding
4339 WARN("unsupported blending in openGl\n");
4342 else
4344 if (gl_info->supported[ARB_VERTEX_BLEND])
4346 static const GLbyte one = 1;
4347 GL_EXTCALL(glWeightbvARB(1, &one));
4348 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4352 /* Point Size ----------------------------------------------*/
4353 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4355 /* no such functionality in the fixed function GL pipeline */
4356 TRACE("Cannot change ptSize here in openGl\n");
4357 /* TODO: Implement this function in using shaders if they are available */
4360 /* Vertex Pointers -----------------------------------------*/
4361 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4363 e = &si->elements[WINED3D_FFP_POSITION];
4365 if (curVBO != e->data.buffer_object)
4367 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4368 checkGLcall("glBindBufferARB");
4369 curVBO = e->data.buffer_object;
4372 TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
4373 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4374 e->data.addr + state->load_base_vertex_index * e->stride);
4375 gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4376 e->data.addr + state->load_base_vertex_index * e->stride);
4377 checkGLcall("glVertexPointer(...)");
4378 gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
4379 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4382 /* Normals -------------------------------------------------*/
4383 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4385 e = &si->elements[WINED3D_FFP_NORMAL];
4387 if (curVBO != e->data.buffer_object)
4389 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4390 checkGLcall("glBindBufferARB");
4391 curVBO = e->data.buffer_object;
4394 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4395 e->data.addr + state->load_base_vertex_index * e->stride);
4396 gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
4397 e->data.addr + state->load_base_vertex_index * e->stride);
4398 checkGLcall("glNormalPointer(...)");
4399 gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
4400 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4403 else
4405 gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
4406 checkGLcall("glNormal3f(0, 0, 0)");
4409 /* Diffuse Colour --------------------------------------------*/
4410 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4412 e = &si->elements[WINED3D_FFP_DIFFUSE];
4414 if (curVBO != e->data.buffer_object)
4416 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4417 checkGLcall("glBindBufferARB");
4418 curVBO = e->data.buffer_object;
4421 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4422 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4423 e->data.addr + state->load_base_vertex_index * e->stride);
4424 gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4425 e->data.addr + state->load_base_vertex_index * e->stride);
4426 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4427 gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
4428 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4431 else
4433 gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4434 checkGLcall("glColor4f(1, 1, 1, 1)");
4437 /* Specular Colour ------------------------------------------*/
4438 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4440 TRACE("setting specular colour\n");
4442 e = &si->elements[WINED3D_FFP_SPECULAR];
4444 if (gl_info->supported[EXT_SECONDARY_COLOR])
4446 GLenum type = e->format->gl_vtx_type;
4447 GLint format = e->format->gl_vtx_format;
4449 if (curVBO != e->data.buffer_object)
4451 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4452 checkGLcall("glBindBufferARB");
4453 curVBO = e->data.buffer_object;
4456 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4458 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4459 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4460 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4461 * 4 component secondary colors use it
4463 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4464 e->data.addr + state->load_base_vertex_index * e->stride);
4465 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4466 e->data.addr + state->load_base_vertex_index * e->stride));
4467 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4469 else
4471 switch(type)
4473 case GL_UNSIGNED_BYTE:
4474 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4475 e->data.addr + state->load_base_vertex_index * e->stride);
4476 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4477 e->data.addr + state->load_base_vertex_index * e->stride));
4478 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4479 break;
4481 default:
4482 FIXME("Add 4 component specular color pointers for type %x\n", type);
4483 /* Make sure that the right color component is dropped */
4484 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4485 e->data.addr + state->load_base_vertex_index * e->stride);
4486 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4487 e->data.addr + state->load_base_vertex_index * e->stride));
4488 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4491 gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4492 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4494 else
4496 WARN("Specular colour is not supported in this GL implementation.\n");
4499 else
4501 if (gl_info->supported[EXT_SECONDARY_COLOR])
4503 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4504 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4506 else
4508 WARN("Specular colour is not supported in this GL implementation.\n");
4512 /* Texture coords -------------------------------------------*/
4513 load_tex_coords(context, si, &curVBO, state);
4516 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4518 const struct wined3d_device *device = context->swapchain->device;
4519 BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4520 BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4522 if (isStateDirty(context, STATE_VDECL)) return;
4523 if (context->numberedArraysLoaded && !load_numbered)
4525 unload_numbered_arrays(context);
4526 context->numberedArraysLoaded = FALSE;
4527 context->numbered_array_mask = 0;
4529 else if (context->namedArraysLoaded)
4531 unload_vertex_data(context->gl_info);
4532 context->namedArraysLoaded = FALSE;
4535 if (load_numbered)
4537 TRACE("Loading numbered arrays\n");
4538 load_numbered_arrays(context, &device->stream_info, state);
4539 context->numberedArraysLoaded = TRUE;
4541 else if (load_named)
4543 TRACE("Loading vertex data\n");
4544 load_vertex_data(context, &device->stream_info, state);
4545 context->namedArraysLoaded = TRUE;
4549 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4551 if (isStateDirty(context, STATE_STREAMSRC))
4552 return;
4553 streamsrc(context, state, STATE_STREAMSRC);
4556 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4558 const struct wined3d_device *device = context->swapchain->device;
4559 const struct wined3d_gl_info *gl_info = context->gl_info;
4560 BOOL useVertexShaderFunction = use_vs(state);
4561 BOOL updateFog = FALSE;
4562 BOOL transformed;
4563 BOOL wasrhw = context->last_was_rhw;
4564 unsigned int i;
4566 transformed = device->stream_info.position_transformed;
4567 if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4568 updateFog = TRUE;
4570 context->last_was_rhw = transformed;
4572 /* Don't have to apply the matrices when vertex shaders are used. When
4573 * vshaders are turned off this function will be called again anyway to
4574 * make sure they're properly set. */
4575 if (!useVertexShaderFunction)
4577 /* TODO: Move this mainly to the viewport state and only apply when
4578 * the vp has changed or transformed / untransformed was switched. */
4579 if (wasrhw != context->last_was_rhw
4580 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4581 && !isStateDirty(context, STATE_VIEWPORT))
4582 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4583 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4584 * mode.
4586 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4587 * this check will fail and the matrix not applied again. This is OK because a simple
4588 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4589 * needs of the vertex declaration.
4591 * World and view matrix go into the same gl matrix, so only apply them when neither is
4592 * dirty
4594 if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4595 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4596 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4597 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4598 state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4599 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4600 state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4602 if (context->last_was_vshader)
4604 updateFog = TRUE;
4606 if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4607 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4609 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4611 clipplane(context, state, STATE_CLIPPLANE(i));
4614 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4615 state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4617 else
4619 if(!context->last_was_vshader) {
4620 static BOOL warned = FALSE;
4621 if(!device->vs_clipping) {
4622 /* Disable all clip planes to get defined results on all drivers. See comment in the
4623 * state_clipping state handler
4625 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4627 gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i);
4628 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4631 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4633 FIXME("Clipping not supported with vertex shaders\n");
4634 warned = TRUE;
4637 if (wasrhw)
4639 /* Apply the transform matrices when switching from rhw
4640 * drawing to vertex shaders. Vertex shaders themselves do
4641 * not need it, but the matrices are not reapplied
4642 * automatically when switching back from vertex shaders to
4643 * fixed function processing. So make sure we leave the fixed
4644 * function vertex processing states back in a sane state
4645 * before switching to shaders. */
4646 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4647 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4648 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4649 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4651 updateFog = TRUE;
4653 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4654 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4655 * device->vs_clipping is false.
4657 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4659 clipplane(context, state, STATE_CLIPPLANE(i));
4664 context->last_was_vshader = useVertexShaderFunction;
4665 context->select_shader = 1;
4666 context->load_constants = 1;
4668 if (updateFog)
4669 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4671 if (!useVertexShaderFunction)
4673 unsigned int i;
4675 for (i = 0; i < MAX_TEXTURES; ++i)
4677 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4678 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4682 if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4683 state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4686 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4688 const struct wined3d_surface *target = state->fb->render_targets[0];
4689 const struct wined3d_gl_info *gl_info = context->gl_info;
4690 struct wined3d_viewport vp = state->viewport;
4692 if (vp.width > target->resource.width)
4693 vp.width = target->resource.width;
4694 if (vp.height > target->resource.height)
4695 vp.height = target->resource.height;
4697 gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
4698 checkGLcall("glDepthRange");
4699 /* Note: GL requires lower left, DirectX supplies upper left. This is
4700 * reversed when using offscreen rendering. */
4701 if (context->render_offscreen)
4703 gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
4705 else
4707 UINT width, height;
4709 target->get_drawable_size(context, &width, &height);
4710 gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)),
4711 vp.width, vp.height);
4714 checkGLcall("glViewport");
4717 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4719 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4720 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4721 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4722 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4723 /* Update the position fixup. */
4724 context->load_constants = 1;
4727 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4729 const struct wined3d_gl_info *gl_info = context->gl_info;
4730 UINT Index = state_id - STATE_ACTIVELIGHT(0);
4731 const struct wined3d_light_info *lightInfo = state->lights[Index];
4733 if (!lightInfo)
4735 gl_info->gl_ops.gl.p_glDisable(GL_LIGHT0 + Index);
4736 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4738 else
4740 float quad_att;
4741 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4743 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4744 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
4745 gl_info->gl_ops.gl.p_glPushMatrix();
4746 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4748 /* Diffuse: */
4749 colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4750 colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4751 colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4752 colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4753 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4754 checkGLcall("glLightfv");
4756 /* Specular */
4757 colRGBA[0] = lightInfo->OriginalParms.specular.r;
4758 colRGBA[1] = lightInfo->OriginalParms.specular.g;
4759 colRGBA[2] = lightInfo->OriginalParms.specular.b;
4760 colRGBA[3] = lightInfo->OriginalParms.specular.a;
4761 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4762 checkGLcall("glLightfv");
4764 /* Ambient */
4765 colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4766 colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4767 colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4768 colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4769 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4770 checkGLcall("glLightfv");
4772 if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4773 quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4774 else
4775 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4777 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4778 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4779 * Attenuation0 to NaN and crashes in the gl lib
4782 switch (lightInfo->OriginalParms.type)
4784 case WINED3D_LIGHT_POINT:
4785 /* Position */
4786 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4787 checkGLcall("glLightfv");
4788 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4789 checkGLcall("glLightf");
4790 /* Attenuation - Are these right? guessing... */
4791 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4792 lightInfo->OriginalParms.attenuation0);
4793 checkGLcall("glLightf");
4794 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4795 lightInfo->OriginalParms.attenuation1);
4796 checkGLcall("glLightf");
4797 if (quad_att < lightInfo->OriginalParms.attenuation2)
4798 quad_att = lightInfo->OriginalParms.attenuation2;
4799 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4800 checkGLcall("glLightf");
4801 /* FIXME: Range */
4802 break;
4804 case WINED3D_LIGHT_SPOT:
4805 /* Position */
4806 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4807 checkGLcall("glLightfv");
4808 /* Direction */
4809 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4810 checkGLcall("glLightfv");
4811 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4812 checkGLcall("glLightf");
4813 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4814 checkGLcall("glLightf");
4815 /* Attenuation - Are these right? guessing... */
4816 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4817 lightInfo->OriginalParms.attenuation0);
4818 checkGLcall("glLightf");
4819 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4820 lightInfo->OriginalParms.attenuation1);
4821 checkGLcall("glLightf");
4822 if (quad_att < lightInfo->OriginalParms.attenuation2)
4823 quad_att = lightInfo->OriginalParms.attenuation2;
4824 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4825 checkGLcall("glLightf");
4826 /* FIXME: Range */
4827 break;
4829 case WINED3D_LIGHT_DIRECTIONAL:
4830 /* Direction */
4831 /* Note GL uses w position of 0 for direction! */
4832 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4833 checkGLcall("glLightfv");
4834 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4835 checkGLcall("glLightf");
4836 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4837 checkGLcall("glLightf");
4838 break;
4840 default:
4841 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4844 /* Restore the modelview matrix */
4845 gl_info->gl_ops.gl.p_glPopMatrix();
4847 gl_info->gl_ops.gl.p_glEnable(GL_LIGHT0 + Index);
4848 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4852 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4854 const struct wined3d_gl_info *gl_info = context->gl_info;
4855 const RECT *r = &state->scissor_rect;
4857 /* Warning: glScissor uses window coordinates, not viewport coordinates,
4858 * so our viewport correction does not apply. Warning2: Even in windowed
4859 * mode the coords are relative to the window, not the screen. */
4860 TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4862 if (context->render_offscreen)
4864 gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4866 else
4868 const struct wined3d_surface *target = state->fb->render_targets[0];
4869 UINT height;
4870 UINT width;
4872 target->get_drawable_size(context, &width, &height);
4873 gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4875 checkGLcall("glScissor");
4878 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4880 const struct wined3d_stream_info *stream_info = &context->swapchain->device->stream_info;
4881 const struct wined3d_gl_info *gl_info = context->gl_info;
4883 if (!state->index_buffer || !stream_info->all_vbo)
4885 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4887 else
4889 struct wined3d_buffer *ib = state->index_buffer;
4890 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4894 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4896 const struct wined3d_gl_info *gl_info = context->gl_info;
4898 if (context->render_offscreen)
4900 gl_info->gl_ops.gl.p_glFrontFace(GL_CCW);
4901 checkGLcall("glFrontFace(GL_CCW)");
4903 else
4905 gl_info->gl_ops.gl.p_glFrontFace(GL_CW);
4906 checkGLcall("glFrontFace(GL_CW)");
4910 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4912 static BOOL warned;
4914 if (!warned)
4916 WARN("Point sprite coordinate origin switching not supported.\n");
4917 warned = TRUE;
4921 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4923 const struct wined3d_gl_info *gl_info = context->gl_info;
4924 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4926 if (gl_info->supported[NV_POINT_SPRITE])
4928 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4929 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4933 void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4935 const struct wined3d_gl_info *gl_info = context->gl_info;
4936 const struct wined3d_surface *rt = state->fb->render_targets[0];
4938 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
4940 if (state->render_states[WINED3D_RS_SRGBWRITEENABLE]
4941 && rt->resource.format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
4942 gl_info->gl_ops.gl.p_glEnable(GL_FRAMEBUFFER_SRGB);
4943 else
4944 gl_info->gl_ops.gl.p_glDisable(GL_FRAMEBUFFER_SRGB);
4947 const struct StateEntryTemplate misc_state_template[] = {
4948 { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4949 { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4950 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4951 { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4952 { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4953 { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4954 { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4955 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4956 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4957 { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4958 { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
4959 { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
4960 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4961 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4962 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4963 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4965 /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4966 * vshader loadings are untied from each other
4968 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4969 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4970 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4971 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4972 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4973 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4974 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4975 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4976 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4977 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4978 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4979 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4980 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4981 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4982 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4983 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4984 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4985 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4986 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4987 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4988 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4989 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4990 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4991 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4992 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4993 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4994 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4995 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4996 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4997 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4998 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4999 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5000 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5001 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5002 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5003 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5004 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5005 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5006 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5007 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5008 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5009 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5010 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5011 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5012 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5013 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5014 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5015 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5016 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5017 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5019 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
5020 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
5021 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
5022 { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
5023 { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
5024 { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
5025 { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
5026 { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
5027 { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
5028 { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
5029 { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
5030 { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
5031 { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
5032 { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
5033 { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
5034 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
5035 { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5036 { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5037 { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5038 { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
5039 { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
5040 { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
5042 { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
5044 { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
5045 { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
5046 { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
5047 { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
5048 { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
5050 { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
5051 { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5052 { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5053 { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5054 { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5055 { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5056 { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5057 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
5058 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
5059 { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5060 { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5061 { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5062 { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5063 { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5064 { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5065 { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5066 { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5067 { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5068 { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5069 { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5070 { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5071 { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5072 { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5073 { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5074 { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5075 { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5076 { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5077 { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5078 { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5079 { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5080 { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5081 { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5082 { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5083 { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5084 { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5085 { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5086 { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5087 { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5088 { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5089 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5090 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5091 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5092 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5093 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5094 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
5095 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5096 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5097 { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5098 { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5099 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5100 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5101 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5102 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5103 { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5104 { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5105 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5106 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5107 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5108 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5109 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5110 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5111 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5112 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5113 { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5114 { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5115 /* Samplers */
5116 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5117 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5118 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5119 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5120 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5121 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5122 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5123 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5124 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5125 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5126 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5127 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5128 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5129 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5130 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5131 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5132 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5133 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5134 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5135 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5136 { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
5137 { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
5138 { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
5139 { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
5140 { STATE_GEOMETRY_SHADER, { STATE_GEOMETRY_SHADER, state_geometry_shader}, WINED3D_GL_EXT_NONE },
5141 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5144 const struct StateEntryTemplate vp_ffp_states[] =
5146 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5147 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5148 { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5149 { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5150 /* Clip planes */
5151 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5152 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5153 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5154 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5155 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5156 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5157 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5158 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5159 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5160 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5161 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5162 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5163 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5164 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5165 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5166 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5167 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5168 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5169 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5170 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5171 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5172 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5173 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5174 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5175 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5176 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5177 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5178 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5179 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5180 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5181 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5182 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5183 /* Lights */
5184 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5185 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5186 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5187 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5188 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5189 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5190 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5191 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5192 /* Viewport */
5193 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5194 /* Transform states follow */
5195 { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5196 { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5197 { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5198 { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5199 { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5200 { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5201 { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5202 { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5203 { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5204 { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5205 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5206 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5207 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5208 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5209 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5210 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5211 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5212 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5396 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5397 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5400 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5401 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5402 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5403 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5405 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5406 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5407 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5411 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5412 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5413 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5414 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5415 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5416 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5417 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5418 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5419 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5420 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5421 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5422 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5423 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5424 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5425 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5426 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5427 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5428 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5429 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5430 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5431 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5432 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5433 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5434 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5435 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5436 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5437 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5438 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5439 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5440 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5441 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5442 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5443 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5444 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5445 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5446 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5447 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5448 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5449 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5450 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5451 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5452 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5453 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5454 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5455 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5456 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5457 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5458 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5459 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5460 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5461 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5462 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5463 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5464 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5465 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5466 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5467 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5468 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5469 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5470 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5471 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5472 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5473 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5474 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5475 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5476 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5477 /* Fog */
5478 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5479 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5480 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5481 { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5482 { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5483 { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5484 { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5485 { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5486 { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5487 { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5488 { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5489 { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5490 { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5491 { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5492 { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5493 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5494 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5495 { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5496 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5497 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5498 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5499 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5500 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5501 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5502 { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5503 { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5504 { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5505 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5506 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5507 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5508 { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5509 { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5511 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5512 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5513 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5515 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5516 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5517 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5518 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5519 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5520 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5521 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5522 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5523 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5524 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5525 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5526 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5527 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5528 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5529 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5530 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5531 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5532 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5533 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5534 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5535 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5536 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5537 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5538 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5539 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5542 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5543 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5544 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5545 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5546 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5547 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5548 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5549 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5550 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5551 { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5552 { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5553 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5554 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5555 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5556 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5557 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5558 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5559 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5560 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5561 { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5562 { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5563 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5564 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5565 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5566 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5567 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5568 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5569 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5570 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5571 { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5572 { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5573 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5574 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5575 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5576 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5577 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5578 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5579 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5580 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5581 { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5582 { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5583 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5584 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5585 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5586 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5587 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5588 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5589 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5590 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5591 { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5592 { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5593 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5594 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5595 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5596 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5597 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5598 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5599 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5600 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5601 { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5602 { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5603 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5604 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5605 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5606 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5607 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5608 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5609 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5610 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5611 { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5612 { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5613 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5614 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5615 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5616 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5617 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5618 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5619 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5620 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5621 { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5622 { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5623 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5624 { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5625 { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5626 { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5627 { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5628 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5629 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5630 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5631 { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5632 { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5633 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5634 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5635 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5636 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5637 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5638 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5639 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5640 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5641 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5644 /* Context activation is done by the caller. */
5645 static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5647 static void *ffp_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
5649 return shader_priv;
5652 static void ffp_free(struct wined3d_device *device) {}
5654 static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
5656 caps->max_active_lights = gl_info->limits.lights;
5657 caps->max_vertex_blend_matrices = gl_info->limits.blends;
5658 caps->max_vertex_blend_matrix_index = 0;
5659 /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
5660 caps->vertex_processing_caps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS
5661 | WINED3DVTXPCAPS_MATERIALSOURCE7
5662 | WINED3DVTXPCAPS_POSITIONALLIGHTS
5663 | WINED3DVTXPCAPS_LOCALVIEWER
5664 | WINED3DVTXPCAPS_VERTEXFOG
5665 | WINED3DVTXPCAPS_TEXGEN;
5666 caps->fvf_caps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
5667 caps->max_user_clip_planes = gl_info->limits.clipplanes;
5668 caps->raster_caps = 0;
5669 if (gl_info->supported[NV_FOG_DISTANCE])
5670 caps->raster_caps |= WINED3DPRASTERCAPS_FOGRANGE;
5673 const struct wined3d_vertex_pipe_ops ffp_vertex_pipe =
5675 ffp_enable,
5676 vp_ffp_get_caps,
5677 ffp_alloc,
5678 ffp_free,
5679 vp_ffp_states,
5682 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5684 caps->wined3d_caps = 0;
5685 caps->PrimitiveMiscCaps = 0;
5686 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5687 | WINED3DTEXOPCAPS_ADDSIGNED
5688 | WINED3DTEXOPCAPS_ADDSIGNED2X
5689 | WINED3DTEXOPCAPS_MODULATE
5690 | WINED3DTEXOPCAPS_MODULATE2X
5691 | WINED3DTEXOPCAPS_MODULATE4X
5692 | WINED3DTEXOPCAPS_SELECTARG1
5693 | WINED3DTEXOPCAPS_SELECTARG2
5694 | WINED3DTEXOPCAPS_DISABLE;
5696 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5697 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5698 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5700 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5701 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5702 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5703 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5704 | WINED3DTEXOPCAPS_LERP
5705 | WINED3DTEXOPCAPS_SUBTRACT;
5707 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5708 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5710 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5711 | WINED3DTEXOPCAPS_MULTIPLYADD
5712 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5713 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5714 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5716 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5717 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5719 caps->MaxTextureBlendStages = gl_info->limits.textures;
5720 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5723 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5725 if (TRACE_ON(d3d))
5727 TRACE("Checking support for fixup:\n");
5728 dump_color_fixup_desc(fixup);
5731 /* We only support identity conversions. */
5732 if (is_identity_fixup(fixup))
5734 TRACE("[OK]\n");
5735 return TRUE;
5738 TRACE("[FAILED]\n");
5739 return FALSE;
5742 const struct fragment_pipeline ffp_fragment_pipeline = {
5743 ffp_enable,
5744 ffp_fragment_get_caps,
5745 ffp_alloc,
5746 ffp_free,
5747 ffp_color_fixup_supported,
5748 ffp_fragmentstate_template,
5751 static void none_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5753 static void *none_alloc(const struct wined3d_shader_backend_ops *shader_backend, void *shader_priv)
5755 return shader_priv;
5758 static void none_free(struct wined3d_device *device) {}
5760 static void vp_none_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
5762 memset(caps, 0, sizeof(*caps));
5765 const struct wined3d_vertex_pipe_ops none_vertex_pipe =
5767 none_enable,
5768 vp_none_get_caps,
5769 none_alloc,
5770 none_free,
5771 NULL,
5774 static void fp_none_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5776 memset(caps, 0, sizeof(*caps));
5779 static BOOL fp_none_color_fixup_supported(struct color_fixup_desc fixup)
5781 return is_identity_fixup(fixup);
5784 const struct fragment_pipeline none_fragment_pipe =
5786 none_enable,
5787 fp_none_get_caps,
5788 none_alloc,
5789 none_free,
5790 fp_none_color_fixup_supported,
5791 NULL,
5794 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5796 unsigned int i;
5797 for(i = 0; funcs[i]; i++);
5798 return i;
5801 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5803 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5804 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5807 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5809 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5810 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5811 context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5814 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5816 unsigned int start, last, i;
5818 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5819 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5820 for (i = start; i <= last; ++i)
5822 state_table[i].representative = 0;
5823 state_table[i].apply = state_undefined;
5826 start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
5827 last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5828 for (i = start; i <= last; ++i)
5830 state_table[i].representative = 0;
5831 state_table[i].apply = state_undefined;
5834 start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5835 last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5836 for (i = start; i <= last; ++i)
5838 state_table[i].representative = 0;
5839 state_table[i].apply = state_undefined;
5843 static void validate_state_table(struct StateEntry *state_table)
5845 static const struct
5847 DWORD first;
5848 DWORD last;
5850 rs_holes[] =
5852 { 1, 1},
5853 { 3, 3},
5854 { 17, 18},
5855 { 21, 21},
5856 { 42, 45},
5857 { 47, 47},
5858 { 61, 127},
5859 {149, 150},
5860 {169, 169},
5861 {177, 177},
5862 {196, 197},
5863 { 0, 0},
5865 static const DWORD simple_states[] =
5867 STATE_MATERIAL,
5868 STATE_VDECL,
5869 STATE_STREAMSRC,
5870 STATE_INDEXBUFFER,
5871 STATE_VERTEXSHADERCONSTANT,
5872 STATE_PIXELSHADERCONSTANT,
5873 STATE_VSHADER,
5874 STATE_GEOMETRY_SHADER,
5875 STATE_PIXELSHADER,
5876 STATE_VIEWPORT,
5877 STATE_SCISSORRECT,
5878 STATE_FRONTFACE,
5879 STATE_POINTSPRITECOORDORIGIN,
5880 STATE_BASEVERTEXINDEX,
5881 STATE_FRAMEBUFFER
5883 unsigned int i, current;
5885 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5887 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5889 if (!state_table[i].representative)
5890 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5892 else if (state_table[i].representative)
5893 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5895 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5898 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5900 if (!state_table[simple_states[i]].representative)
5901 ERR("State %s (%#x) should have a representative.\n",
5902 debug_d3dstate(simple_states[i]), simple_states[i]);
5905 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5907 DWORD rep = state_table[i].representative;
5908 if (rep)
5910 if (state_table[rep].representative != rep)
5912 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5913 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5914 state_table[i].representative = 0;
5917 if (rep != i)
5919 if (state_table[i].apply)
5920 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5922 else if (!state_table[i].apply)
5924 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5930 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5931 const struct wined3d_gl_info *gl_info, const struct wined3d_vertex_pipe_ops *vertex,
5932 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5934 unsigned int i, type, handlers;
5935 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5936 const struct StateEntryTemplate *cur;
5937 BOOL set[STATE_HIGHEST + 1];
5939 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5941 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5942 StateTable[i].representative = 0;
5943 StateTable[i].apply = state_undefined;
5946 for(type = 0; type < 3; type++) {
5947 /* This switch decides the order in which the states are applied */
5948 switch(type) {
5949 case 0: cur = misc; break;
5950 case 1: cur = fragment->states; break;
5951 case 2: cur = vertex->vp_states; break;
5952 default: cur = NULL; /* Stupid compiler */
5954 if(!cur) continue;
5956 /* GL extension filtering should not prevent multiple handlers being applied from different
5957 * pipeline parts
5959 memset(set, 0, sizeof(set));
5961 for(i = 0; cur[i].state; i++) {
5962 APPLYSTATEFUNC *funcs_array;
5964 /* Only use the first matching state with the available extension from one template.
5965 * e.g.
5966 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5967 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5969 * if GL_XYZ_fancy is supported, ignore the 2nd line
5971 if(set[cur[i].state]) continue;
5972 /* Skip state lines depending on unsupported extensions */
5973 if (!gl_info->supported[cur[i].extension]) continue;
5974 set[cur[i].state] = TRUE;
5975 /* In some cases having an extension means that nothing has to be
5976 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5977 * supported, the texture coordinate fixup can be ignored. If the
5978 * apply function is used, mark the state set(done above) to prevent
5979 * applying later lines, but do not record anything in the state
5980 * table
5982 if (!cur[i].content.representative) continue;
5984 handlers = num_handlers(multistate_funcs[cur[i].state]);
5985 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5986 switch(handlers) {
5987 case 0:
5988 StateTable[cur[i].state].apply = cur[i].content.apply;
5989 break;
5990 case 1:
5991 StateTable[cur[i].state].apply = multistate_apply_2;
5992 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5994 sizeof(**dev_multistate_funcs) * 2);
5995 if (!dev_multistate_funcs[cur[i].state]) {
5996 goto out_of_mem;
5999 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
6000 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
6001 break;
6002 case 2:
6003 StateTable[cur[i].state].apply = multistate_apply_3;
6004 funcs_array = HeapReAlloc(GetProcessHeap(),
6006 dev_multistate_funcs[cur[i].state],
6007 sizeof(**dev_multistate_funcs) * 3);
6008 if (!funcs_array) {
6009 goto out_of_mem;
6012 dev_multistate_funcs[cur[i].state] = funcs_array;
6013 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
6014 break;
6015 default:
6016 ERR("Unexpected amount of state handlers for state %u: %u\n",
6017 cur[i].state, handlers + 1);
6020 if(StateTable[cur[i].state].representative &&
6021 StateTable[cur[i].state].representative != cur[i].content.representative) {
6022 FIXME("State %u has different representatives in different pipeline parts\n",
6023 cur[i].state);
6025 StateTable[cur[i].state].representative = cur[i].content.representative;
6029 prune_invalid_states(StateTable, gl_info);
6030 validate_state_table(StateTable);
6032 return WINED3D_OK;
6034 out_of_mem:
6035 for (i = 0; i <= STATE_HIGHEST; ++i) {
6036 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
6039 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
6041 return E_OUTOFMEMORY;