d3dx9/tests: Add basic tests for ID3DXRenderToEnvMap.
[wine/multimedia.git] / dlls / wined3d / state.c
blob4400886c2caae41fe83485b975c85660c2e89530
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 /* GL locking for state handlers 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->strided_streams.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->strided_streams.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_mask ? GL_DST_ALPHA : GL_ONE;
383 case WINED3D_BLEND_INVDESTALPHA:
384 return dst_format->alpha_mask ? 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 const struct wined3d_device *device = context->swapchain->device;
604 /* Vertex and pixel shader states will call a shader upload, don't do
605 * anything as long one of them has an update pending. */
606 if (isStateDirty(context, STATE_VDECL)
607 || isStateDirty(context, STATE_PIXELSHADER))
608 return;
610 device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
613 static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
615 const struct wined3d_gl_info *gl_info = context->gl_info;
616 DWORD enable = 0xffffffff;
617 DWORD disable = 0x00000000;
619 if (use_vs(state))
621 const struct wined3d_device *device = context->swapchain->device;
623 if (!device->vs_clipping)
625 /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
626 * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
627 * conditions I got sick of tracking down. The shader state handler disables all clip planes because
628 * of that - don't do anything here and keep them disabled
630 if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
632 static BOOL warned = FALSE;
633 if(!warned) {
634 FIXME("Clipping not supported with vertex shaders\n");
635 warned = TRUE;
638 return;
641 /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
642 * hardcoded into the shader. Update the shader to update the enabled clipplanes */
643 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
645 device->shader_backend->shader_select(context, use_ps(state), TRUE);
646 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
647 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
651 /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
652 * of already set values
655 /* If enabling / disabling all
656 * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
658 if (state->render_states[WINED3D_RS_CLIPPING])
660 enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
661 disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
663 else
665 disable = 0xffffffff;
666 enable = 0x00;
669 if (enable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE0);
670 if (enable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE1);
671 if (enable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE2);
672 if (enable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE3);
673 if (enable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE4);
674 if (enable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glEnable(GL_CLIP_PLANE5);
675 checkGLcall("clip plane enable");
677 if (disable & WINED3DCLIPPLANE0) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0);
678 if (disable & WINED3DCLIPPLANE1) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE1);
679 if (disable & WINED3DCLIPPLANE2) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE2);
680 if (disable & WINED3DCLIPPLANE3) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE3);
681 if (disable & WINED3DCLIPPLANE4) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE4);
682 if (disable & WINED3DCLIPPLANE5) gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE5);
683 checkGLcall("clip plane disable");
686 static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
688 const struct wined3d_gl_info *gl_info = context->gl_info;
689 /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
690 * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
691 * specular color. This is wrong:
692 * Separate specular color means the specular colour is maintained separately, whereas
693 * single color means it is merged in. However in both cases they are being used to
694 * some extent.
695 * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
696 * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
697 * running 1.4 yet!
700 * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
701 * Instead, we need to setup the FinalCombiner properly.
703 * The default setup for the FinalCombiner is:
705 * <variable> <input> <mapping> <usage>
706 * GL_VARIABLE_A_NV GL_FOG, GL_UNSIGNED_IDENTITY_NV GL_ALPHA
707 * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV GL_UNSIGNED_IDENTITY_NV GL_RGB
708 * GL_VARIABLE_C_NV GL_FOG GL_UNSIGNED_IDENTITY_NV GL_RGB
709 * GL_VARIABLE_D_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
710 * GL_VARIABLE_E_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
711 * GL_VARIABLE_F_NV GL_ZERO GL_UNSIGNED_IDENTITY_NV GL_RGB
712 * GL_VARIABLE_G_NV GL_SPARE0_NV GL_UNSIGNED_IDENTITY_NV GL_ALPHA
714 * That's pretty much fine as it is, except for variable B, which needs to take
715 * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
716 * whether WINED3D_RS_SPECULARENABLE is enabled or not.
719 TRACE("Setting specular enable state and materials\n");
720 if (state->render_states[WINED3D_RS_SPECULARENABLE])
722 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
723 checkGLcall("glMaterialfv");
725 if (state->material.power > gl_info->limits.shininess)
727 /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
728 * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
729 * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
730 * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
731 * them, it should be safe to do so without major visual distortions.
733 WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
734 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
736 else
738 gl_info->gl_ops.gl.p_glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
740 checkGLcall("glMaterialf(GL_SHININESS)");
742 if (gl_info->supported[EXT_SECONDARY_COLOR])
743 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_SUM_EXT);
744 else
745 TRACE("Specular colors cannot be enabled in this version of opengl\n");
746 checkGLcall("glEnable(GL_COLOR_SUM)");
748 if (gl_info->supported[NV_REGISTER_COMBINERS])
750 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
751 checkGLcall("glFinalCombinerInputNV()");
753 } else {
754 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
756 /* for the case of enabled lighting: */
757 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
758 checkGLcall("glMaterialfv");
760 /* for the case of disabled lighting: */
761 if (gl_info->supported[EXT_SECONDARY_COLOR])
762 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_SUM_EXT);
763 else
764 TRACE("Specular colors cannot be disabled in this version of opengl\n");
765 checkGLcall("glDisable(GL_COLOR_SUM)");
767 if (gl_info->supported[NV_REGISTER_COMBINERS])
769 GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
770 checkGLcall("glFinalCombinerInputNV()");
774 TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
775 state->material.diffuse.r, state->material.diffuse.g,
776 state->material.diffuse.b, state->material.diffuse.a);
777 TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
778 state->material.ambient.r, state->material.ambient.g,
779 state->material.ambient.b, state->material.ambient.a);
780 TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
781 state->material.specular.r, state->material.specular.g,
782 state->material.specular.b, state->material.specular.a);
783 TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
784 state->material.emissive.r, state->material.emissive.g,
785 state->material.emissive.b, state->material.emissive.a);
787 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
788 checkGLcall("glMaterialfv(GL_AMBIENT)");
789 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
790 checkGLcall("glMaterialfv(GL_DIFFUSE)");
791 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
792 checkGLcall("glMaterialfv(GL_EMISSION)");
795 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
797 const struct wined3d_gl_info *gl_info = context->gl_info;
798 unsigned int i;
800 /* Note the texture color applies to all textures whereas
801 * GL_TEXTURE_ENV_COLOR applies to active only. */
802 float col[4];
803 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
805 /* And now the default texture color as well */
806 for (i = 0; i < gl_info->limits.texture_stages; ++i)
808 /* Note the WINED3D_RS value applies to all textures, but GL has one
809 * per texture, so apply it now ready to be used! */
810 context_active_texture(context, gl_info, i);
812 gl_info->gl_ops.gl.p_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
813 checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
817 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
818 GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
820 const struct wined3d_gl_info *gl_info = context->gl_info;
822 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
823 checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
824 GL_EXTCALL(glActiveStencilFaceEXT(face));
825 checkGLcall("glActiveStencilFaceEXT(...)");
826 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
827 checkGLcall("glStencilFunc(...)");
828 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
829 checkGLcall("glStencilOp(...)");
832 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
834 switch (op)
836 case WINED3D_STENCIL_OP_KEEP:
837 return GL_KEEP;
838 case WINED3D_STENCIL_OP_ZERO:
839 return GL_ZERO;
840 case WINED3D_STENCIL_OP_REPLACE:
841 return GL_REPLACE;
842 case WINED3D_STENCIL_OP_INCR_SAT:
843 return GL_INCR;
844 case WINED3D_STENCIL_OP_DECR_SAT:
845 return GL_DECR;
846 case WINED3D_STENCIL_OP_INVERT:
847 return GL_INVERT;
848 case WINED3D_STENCIL_OP_INCR:
849 return GL_INCR_WRAP_EXT;
850 case WINED3D_STENCIL_OP_DECR:
851 return GL_DECR_WRAP_EXT;
852 default:
853 FIXME("Unrecognized stencil op %#x.\n", op);
854 return GL_KEEP;
858 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
860 const struct wined3d_gl_info *gl_info = context->gl_info;
861 DWORD onesided_enable = FALSE;
862 DWORD twosided_enable = FALSE;
863 GLint func = GL_ALWAYS;
864 GLint func_ccw = GL_ALWAYS;
865 GLint ref = 0;
866 GLuint mask = 0;
867 GLint stencilFail = GL_KEEP;
868 GLint depthFail = GL_KEEP;
869 GLint stencilPass = GL_KEEP;
870 GLint stencilFail_ccw = GL_KEEP;
871 GLint depthFail_ccw = GL_KEEP;
872 GLint stencilPass_ccw = GL_KEEP;
874 /* No stencil test without a stencil buffer. */
875 if (!state->fb->depth_stencil)
877 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
878 checkGLcall("glDisable GL_STENCIL_TEST");
879 return;
882 onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
883 twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
884 if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
885 func = GL_ALWAYS;
886 if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
887 func_ccw = GL_ALWAYS;
888 ref = state->render_states[WINED3D_RS_STENCILREF];
889 mask = state->render_states[WINED3D_RS_STENCILMASK];
890 stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
891 depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
892 stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
893 stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
894 depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
895 stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
897 TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
898 "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
899 "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
900 onesided_enable, twosided_enable, ref, mask,
901 func, stencilFail, depthFail, stencilPass,
902 func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
904 if (twosided_enable && onesided_enable)
906 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
907 checkGLcall("glEnable GL_STENCIL_TEST");
909 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
911 /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
912 * which has an effect on the code below too. If we apply the front face
913 * afterwards, we are sure that the active stencil face is set to front,
914 * and other stencil functions which do not use two sided stencil do not have
915 * to set it back
917 renderstate_stencil_twosided(context, GL_BACK,
918 func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
919 renderstate_stencil_twosided(context, GL_FRONT,
920 func, ref, mask, stencilFail, depthFail, stencilPass);
922 else if (gl_info->supported[ATI_SEPARATE_STENCIL])
924 GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
925 checkGLcall("glStencilFuncSeparateATI(...)");
926 GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
927 checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
928 GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
929 checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
930 } else {
931 ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
934 else if(onesided_enable)
936 if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
938 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
939 checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
942 /* This code disables the ATI extension as well, since the standard stencil functions are equal
943 * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
945 gl_info->gl_ops.gl.p_glEnable(GL_STENCIL_TEST);
946 checkGLcall("glEnable GL_STENCIL_TEST");
947 gl_info->gl_ops.gl.p_glStencilFunc(func, ref, mask);
948 checkGLcall("glStencilFunc(...)");
949 gl_info->gl_ops.gl.p_glStencilOp(stencilFail, depthFail, stencilPass);
950 checkGLcall("glStencilOp(...)");
952 else
954 gl_info->gl_ops.gl.p_glDisable(GL_STENCIL_TEST);
955 checkGLcall("glDisable GL_STENCIL_TEST");
959 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
961 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
962 const struct wined3d_gl_info *gl_info = context->gl_info;
964 GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
965 checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
966 gl_info->gl_ops.gl.p_glStencilMask(mask);
967 checkGLcall("glStencilMask");
968 GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
969 checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
970 gl_info->gl_ops.gl.p_glStencilMask(mask);
973 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
975 DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
976 const struct wined3d_gl_info *gl_info = context->gl_info;
978 gl_info->gl_ops.gl.p_glStencilMask(mask);
979 checkGLcall("glStencilMask");
982 static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
984 const struct wined3d_gl_info *gl_info = context->gl_info;
986 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
988 if (!state->render_states[WINED3D_RS_FOGENABLE])
989 return;
991 /* Table fog on: Never use fog coords, and use per-fragment fog */
992 if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
994 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST);
995 if (context->fog_coord)
997 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
998 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
999 context->fog_coord = FALSE;
1002 /* Range fog is only used with per-vertex fog in d3d */
1003 if (gl_info->supported[NV_FOG_DISTANCE])
1005 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1006 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1008 return;
1011 /* Otherwise use per-vertex fog in any case */
1012 gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_FASTEST);
1014 if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
1016 /* No fog at all, or transformed vertices: Use fog coord */
1017 if (!context->fog_coord)
1019 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1020 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
1021 context->fog_coord = TRUE;
1024 else
1026 /* Otherwise, use the fragment depth */
1027 if (context->fog_coord)
1029 gl_info->gl_ops.gl.p_glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
1030 checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
1031 context->fog_coord = FALSE;
1034 if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
1036 if (gl_info->supported[NV_FOG_DISTANCE])
1038 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
1039 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
1041 else
1043 WARN("Range fog enabled, but not supported by this GL implementation.\n");
1046 else if (gl_info->supported[NV_FOG_DISTANCE])
1048 gl_info->gl_ops.gl.p_glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
1049 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
1054 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1056 const struct wined3d_gl_info *gl_info = context->gl_info;
1057 float fogstart, fogend;
1058 union {
1059 DWORD d;
1060 float f;
1061 } tmpvalue;
1063 switch(context->fog_source) {
1064 case FOGSOURCE_VS:
1065 fogstart = 1.0f;
1066 fogend = 0.0f;
1067 break;
1069 case FOGSOURCE_COORD:
1070 fogstart = 255.0f;
1071 fogend = 0.0f;
1072 break;
1074 case FOGSOURCE_FFP:
1075 tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
1076 fogstart = tmpvalue.f;
1077 tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
1078 fogend = tmpvalue.f;
1079 /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
1080 if(fogstart == fogend) {
1081 fogstart = -INFINITY;
1082 fogend = 0.0f;
1084 break;
1086 default:
1087 /* This should not happen.context->fog_source is set in wined3d, not the app.
1088 * Still this is needed to make the compiler happy
1090 ERR("Unexpected fog coordinate source\n");
1091 fogstart = 0.0f;
1092 fogend = 0.0f;
1095 gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, fogstart);
1096 checkGLcall("glFogf(GL_FOG_START, fogstart)");
1097 TRACE("Fog Start == %f\n", fogstart);
1099 gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, fogend);
1100 checkGLcall("glFogf(GL_FOG_END, fogend)");
1101 TRACE("Fog End == %f\n", fogend);
1104 void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1106 const struct wined3d_gl_info *gl_info = context->gl_info;
1107 enum fogsource new_source;
1109 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
1111 if (!state->render_states[WINED3D_RS_FOGENABLE])
1113 /* No fog? Disable it, and we're done :-) */
1114 glDisableWINE(GL_FOG);
1115 checkGLcall("glDisable GL_FOG");
1116 return;
1119 /* Fog Rules:
1121 * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
1122 * It can use the Z value of the vertex, or the alpha component of the specular color.
1123 * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
1124 * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
1125 * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
1127 * FOGTABLEMODE != NONE:
1128 * The Z value is used, with the equation specified, no matter what vertex type.
1130 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
1131 * Per vertex fog is calculated using the specified fog equation and the parameters
1133 * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
1134 * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
1135 * Linear fog with start = 255.0, end = 0.0, input comes from the specular color
1138 * Rules for vertex fog with shaders:
1140 * When mixing fixed function functionality with the programmable pipeline, D3D expects
1141 * the fog computation to happen during transformation while openGL expects it to happen
1142 * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
1143 * the pixel shader while openGL always expects the pixel shader to handle the blending.
1144 * To solve this problem, WineD3D does:
1145 * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
1146 * shader,
1147 * and 2) disables the fog computation (in either the fixed function or programmable
1148 * rasterizer) if using a vertex program.
1150 * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
1151 * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
1152 * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
1153 * the specular color, a vertex shader counts as pretransformed geometry in this case.
1154 * There are some GL differences between specular fog coords and vertex shaders though.
1156 * With table fog the vertex shader fog coordinate is ignored.
1158 * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
1159 * without shaders).
1162 /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
1163 * the system will apply only pixel(=table) fog effects."
1165 if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
1167 if (use_vs(state))
1169 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1170 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1171 new_source = FOGSOURCE_VS;
1173 else
1175 switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
1177 /* If processed vertices are used, fall through to the NONE case */
1178 case WINED3D_FOG_EXP:
1179 if (!context->last_was_rhw)
1181 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1182 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1183 new_source = FOGSOURCE_FFP;
1184 break;
1186 /* drop through */
1188 case WINED3D_FOG_EXP2:
1189 if (!context->last_was_rhw)
1191 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1192 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1193 new_source = FOGSOURCE_FFP;
1194 break;
1196 /* drop through */
1198 case WINED3D_FOG_LINEAR:
1199 if (!context->last_was_rhw)
1201 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1202 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1203 new_source = FOGSOURCE_FFP;
1204 break;
1206 /* drop through */
1208 case WINED3D_FOG_NONE:
1209 /* Both are none? According to msdn the alpha channel of the specular
1210 * color contains a fog factor. Set it in drawStridedSlow.
1211 * Same happens with Vertexfog on transformed vertices
1213 new_source = FOGSOURCE_COORD;
1214 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1215 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1216 break;
1218 default:
1219 FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
1220 state->render_states[WINED3D_RS_FOGVERTEXMODE]);
1221 new_source = FOGSOURCE_FFP; /* Make the compiler happy */
1224 } else {
1225 new_source = FOGSOURCE_FFP;
1227 switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
1229 case WINED3D_FOG_EXP:
1230 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP);
1231 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
1232 break;
1234 case WINED3D_FOG_EXP2:
1235 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_EXP2);
1236 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
1237 break;
1239 case WINED3D_FOG_LINEAR:
1240 gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
1241 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
1242 break;
1244 case WINED3D_FOG_NONE: /* Won't happen */
1245 default:
1246 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
1247 state->render_states[WINED3D_RS_FOGTABLEMODE]);
1251 glEnableWINE(GL_FOG);
1252 checkGLcall("glEnable GL_FOG");
1253 if (new_source != context->fog_source)
1255 context->fog_source = new_source;
1256 state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
1260 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1262 const struct wined3d_gl_info *gl_info = context->gl_info;
1263 float col[4];
1265 D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
1266 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, &col[0]);
1267 checkGLcall("glFog GL_FOG_COLOR");
1270 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1272 const struct wined3d_gl_info *gl_info = context->gl_info;
1273 union {
1274 DWORD d;
1275 float f;
1276 } tmpvalue;
1278 tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
1279 gl_info->gl_ops.gl.p_glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
1280 checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
1283 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1285 const struct wined3d_device *device = context->swapchain->device;
1286 const struct wined3d_gl_info *gl_info = context->gl_info;
1287 GLenum Parm = 0;
1289 /* Depends on the decoded vertex declaration to read the existence of diffuse data.
1290 * The vertex declaration will call this function if the fixed function pipeline is used.
1293 if(isStateDirty(context, STATE_VDECL)) {
1294 return;
1297 context->num_untracked_materials = 0;
1298 if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
1299 && state->render_states[WINED3D_RS_COLORVERTEX])
1301 TRACE("diff %d, amb %d, emis %d, spec %d\n",
1302 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
1303 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
1304 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
1305 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
1307 if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1309 if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1310 Parm = GL_AMBIENT_AND_DIFFUSE;
1311 else
1312 Parm = GL_DIFFUSE;
1313 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1315 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1316 context->num_untracked_materials++;
1318 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1320 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1321 context->num_untracked_materials++;
1324 else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1326 Parm = GL_AMBIENT;
1327 if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1329 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
1330 context->num_untracked_materials++;
1332 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1334 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1335 context->num_untracked_materials++;
1338 else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1340 Parm = GL_EMISSION;
1341 if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1343 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
1344 context->num_untracked_materials++;
1347 else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
1349 Parm = GL_SPECULAR;
1353 /* Nothing changed, return. */
1354 if (Parm == context->tracking_parm) return;
1356 if (!Parm)
1358 gl_info->gl_ops.gl.p_glDisable(GL_COLOR_MATERIAL);
1359 checkGLcall("glDisable GL_COLOR_MATERIAL");
1361 else
1363 gl_info->gl_ops.gl.p_glColorMaterial(GL_FRONT_AND_BACK, Parm);
1364 checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
1365 gl_info->gl_ops.gl.p_glEnable(GL_COLOR_MATERIAL);
1366 checkGLcall("glEnable(GL_COLOR_MATERIAL)");
1369 /* Apparently calls to glMaterialfv are ignored for properties we're
1370 * tracking with glColorMaterial, so apply those here. */
1371 switch (context->tracking_parm)
1373 case GL_AMBIENT_AND_DIFFUSE:
1374 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1375 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1376 checkGLcall("glMaterialfv");
1377 break;
1379 case GL_DIFFUSE:
1380 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
1381 checkGLcall("glMaterialfv");
1382 break;
1384 case GL_AMBIENT:
1385 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
1386 checkGLcall("glMaterialfv");
1387 break;
1389 case GL_EMISSION:
1390 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
1391 checkGLcall("glMaterialfv");
1392 break;
1394 case GL_SPECULAR:
1395 /* Only change material color if specular is enabled, otherwise it is set to black */
1396 if (state->render_states[WINED3D_RS_SPECULARENABLE])
1398 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
1399 checkGLcall("glMaterialfv");
1401 else
1403 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
1404 gl_info->gl_ops.gl.p_glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
1405 checkGLcall("glMaterialfv");
1407 break;
1410 context->tracking_parm = Parm;
1413 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1415 const struct wined3d_gl_info *gl_info = context->gl_info;
1416 union
1418 DWORD d;
1419 struct wined3d_line_pattern lp;
1420 } tmppattern;
1421 tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
1423 TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1425 if (tmppattern.lp.repeat_factor)
1427 gl_info->gl_ops.gl.p_glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
1428 checkGLcall("glLineStipple(repeat, linepattern)");
1429 gl_info->gl_ops.gl.p_glEnable(GL_LINE_STIPPLE);
1430 checkGLcall("glEnable(GL_LINE_STIPPLE);");
1432 else
1434 gl_info->gl_ops.gl.p_glDisable(GL_LINE_STIPPLE);
1435 checkGLcall("glDisable(GL_LINE_STIPPLE);");
1439 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1441 const struct wined3d_gl_info *gl_info = context->gl_info;
1443 if (isStateDirty(context, STATE_VDECL))
1444 return;
1446 /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
1447 * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
1448 * by zero and is not properly defined in opengl, so avoid it
1450 if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
1451 && (context->swapchain->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
1453 gl_info->gl_ops.gl.p_glEnable(GL_NORMALIZE);
1454 checkGLcall("glEnable(GL_NORMALIZE);");
1456 else
1458 gl_info->gl_ops.gl.p_glDisable(GL_NORMALIZE);
1459 checkGLcall("glDisable(GL_NORMALIZE);");
1463 static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1465 union {
1466 DWORD d;
1467 float f;
1468 } tmpvalue;
1470 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1471 if (tmpvalue.f != 1.0f)
1473 FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
1475 tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1476 if (tmpvalue.f != 64.0f)
1478 FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
1483 static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1485 const struct wined3d_gl_info *gl_info = context->gl_info;
1486 union
1488 DWORD d;
1489 float f;
1490 } min, max;
1492 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1493 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1495 /* Max point size trumps min point size */
1496 if(min.f > max.f) {
1497 min.f = max.f;
1500 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
1501 checkGLcall("glPointParameterfEXT(...)");
1502 GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
1503 checkGLcall("glPointParameterfEXT(...)");
1506 static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1508 const struct wined3d_gl_info *gl_info = context->gl_info;
1509 union
1511 DWORD d;
1512 float f;
1513 } min, max;
1515 min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
1516 max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
1518 /* Max point size trumps min point size */
1519 if(min.f > max.f) {
1520 min.f = max.f;
1523 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
1524 checkGLcall("glPointParameterfARB(...)");
1525 GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
1526 checkGLcall("glPointParameterfARB(...)");
1529 static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1531 const struct wined3d_gl_info *gl_info = context->gl_info;
1532 /* TODO: Group this with the viewport */
1534 * POINTSCALEENABLE controls how point size value is treated. If set to
1535 * true, the point size is scaled with respect to height of viewport.
1536 * When set to false point size is in pixels.
1539 /* Default values */
1540 GLfloat att[3] = {1.0f, 0.0f, 0.0f};
1541 union {
1542 DWORD d;
1543 float f;
1544 } pointSize, A, B, C;
1546 pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
1547 A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
1548 B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
1549 C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
1551 if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1553 DWORD h = state->viewport.height;
1554 GLfloat scaleFactor;
1556 if (pointSize.f < gl_info->limits.pointsize_min)
1558 /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
1559 * 0.0f. This means that OpenGL will clamp really small point sizes to the
1560 * driver minimum. To correct for this we need to multiply by the scale factor when sizes
1561 * are less than 1.0f. scale_factor = 1.0f / point_size.
1563 scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
1564 /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
1565 * is 1.0, but then accepts points below that and draws too small points
1567 pointSize.f = gl_info->limits.pointsize_min;
1569 else if(pointSize.f > gl_info->limits.pointsize_max)
1571 /* gl already scales the input to glPointSize,
1572 * d3d scales the result after the point size scale.
1573 * If the point size is bigger than the max size, use the
1574 * scaling to scale it bigger, and set the gl point size to max
1576 scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
1577 TRACE("scale: %f\n", scaleFactor);
1578 pointSize.f = gl_info->limits.pointsize_max;
1579 } else {
1580 scaleFactor = 1.0f;
1582 scaleFactor = powf(h * scaleFactor, 2);
1584 att[0] = A.f / scaleFactor;
1585 att[1] = B.f / scaleFactor;
1586 att[2] = C.f / scaleFactor;
1589 if (gl_info->supported[ARB_POINT_PARAMETERS])
1591 GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
1592 checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
1594 else if (gl_info->supported[EXT_POINT_PARAMETERS])
1596 GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
1597 checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
1599 else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
1601 WARN("POINT_PARAMETERS not supported in this version of opengl\n");
1604 gl_info->gl_ops.gl.p_glPointSize(pointSize.f);
1605 checkGLcall("glPointSize(...);");
1608 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1610 WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
1613 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1615 DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
1616 DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
1617 DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
1618 DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
1619 const struct wined3d_gl_info *gl_info = context->gl_info;
1621 TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
1622 mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
1623 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
1624 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
1625 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
1626 gl_info->gl_ops.gl.p_glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1627 mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1628 mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1629 mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
1630 checkGLcall("glColorMask(...)");
1632 if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
1633 || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
1635 FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
1636 mask0, mask1, mask2, mask3);
1637 FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
1641 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
1643 GL_EXTCALL(glColorMaskIndexedEXT(index,
1644 mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
1645 mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
1646 mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
1647 mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
1650 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1652 set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
1655 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1657 set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
1660 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1662 set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
1665 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1667 set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
1670 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1672 const struct wined3d_gl_info *gl_info = context->gl_info;
1674 if (state->render_states[WINED3D_RS_LOCALVIEWER])
1676 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
1677 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
1679 else
1681 gl_info->gl_ops.gl.p_glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
1682 checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
1686 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1688 if (state->render_states[WINED3D_RS_LASTPIXEL])
1690 TRACE("Last Pixel Drawing Enabled\n");
1692 else
1694 static BOOL warned;
1695 if (!warned) {
1696 FIXME("Last Pixel Drawing Disabled, not handled yet\n");
1697 warned = TRUE;
1698 } else {
1699 TRACE("Last Pixel Drawing Disabled, not handled yet\n");
1704 static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1706 static BOOL warned;
1708 /* TODO: NV_POINT_SPRITE */
1709 if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1711 /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
1712 FIXME("Point sprites not supported\n");
1713 warned = TRUE;
1717 static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1719 const struct wined3d_gl_info *gl_info = context->gl_info;
1721 if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
1723 gl_info->gl_ops.gl.p_glEnable(GL_POINT_SPRITE_ARB);
1724 checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
1726 else
1728 gl_info->gl_ops.gl.p_glDisable(GL_POINT_SPRITE_ARB);
1729 checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
1733 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1735 if (state->render_states[WINED3D_RS_WRAP0]
1736 || state->render_states[WINED3D_RS_WRAP1]
1737 || state->render_states[WINED3D_RS_WRAP2]
1738 || state->render_states[WINED3D_RS_WRAP3]
1739 || state->render_states[WINED3D_RS_WRAP4]
1740 || state->render_states[WINED3D_RS_WRAP5]
1741 || state->render_states[WINED3D_RS_WRAP6]
1742 || state->render_states[WINED3D_RS_WRAP7]
1743 || state->render_states[WINED3D_RS_WRAP8]
1744 || state->render_states[WINED3D_RS_WRAP9]
1745 || state->render_states[WINED3D_RS_WRAP10]
1746 || state->render_states[WINED3D_RS_WRAP11]
1747 || state->render_states[WINED3D_RS_WRAP12]
1748 || state->render_states[WINED3D_RS_WRAP13]
1749 || state->render_states[WINED3D_RS_WRAP14]
1750 || state->render_states[WINED3D_RS_WRAP15])
1751 FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
1754 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1756 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1757 WARN("Multisample antialiasing not supported by GL.\n");
1760 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1762 const struct wined3d_gl_info *gl_info = context->gl_info;
1764 if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
1766 gl_info->gl_ops.gl.p_glEnable(GL_MULTISAMPLE_ARB);
1767 checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
1769 else
1771 gl_info->gl_ops.gl.p_glDisable(GL_MULTISAMPLE_ARB);
1772 checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
1776 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1778 const struct wined3d_gl_info *gl_info = context->gl_info;
1780 if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
1782 gl_info->gl_ops.gl.p_glEnable(GL_SCISSOR_TEST);
1783 checkGLcall("glEnable(GL_SCISSOR_TEST)");
1785 else
1787 gl_info->gl_ops.gl.p_glDisable(GL_SCISSOR_TEST);
1788 checkGLcall("glDisable(GL_SCISSOR_TEST)");
1792 /* The Direct3D depth bias is specified in normalized depth coordinates. In
1793 * OpenGL the bias is specified in units of "the smallest value that is
1794 * guaranteed to produce a resolvable offset for a given implementation". To
1795 * convert from D3D to GL we need to divide the D3D depth bias by that value.
1796 * There's no practical way to retrieve that value from a given GL
1797 * implementation, but the D3D application has essentially the same problem,
1798 * which makes a guess of the depth buffer format's highest possible value a
1799 * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
1800 * depth slope, and doesn't need to be scaled. */
1801 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1803 const struct wined3d_gl_info *gl_info = context->gl_info;
1805 if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
1806 || state->render_states[WINED3D_RS_DEPTHBIAS])
1808 const struct wined3d_surface *depth = state->fb->depth_stencil;
1809 float scale;
1811 union
1813 DWORD d;
1814 float f;
1815 } scale_bias, const_bias;
1817 scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
1818 const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
1820 gl_info->gl_ops.gl.p_glEnable(GL_POLYGON_OFFSET_FILL);
1821 checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
1823 if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
1825 float bias = -(float)const_bias.d;
1826 gl_info->gl_ops.gl.p_glPolygonOffset(bias, bias);
1827 checkGLcall("glPolygonOffset");
1829 else
1831 if (depth)
1833 const struct wined3d_format *fmt = depth->resource.format;
1834 scale = powf(2, fmt->depth_size) - 1;
1835 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
1836 debug_d3dformat(fmt->id), scale);
1838 else
1840 /* The context manager will reapply this state on a depth stencil change */
1841 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
1842 scale = 0.0f;
1845 gl_info->gl_ops.gl.p_glPolygonOffset(scale_bias.f, const_bias.f * scale);
1846 checkGLcall("glPolygonOffset(...)");
1849 else
1851 gl_info->gl_ops.gl.p_glDisable(GL_POLYGON_OFFSET_FILL);
1852 checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
1856 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1858 if (state->render_states[WINED3D_RS_ZVISIBLE])
1859 FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
1862 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1864 const struct wined3d_gl_info *gl_info = context->gl_info;
1866 if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
1868 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1869 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
1871 else
1873 gl_info->gl_ops.gl.p_glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1874 checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
1878 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1880 if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
1881 FIXME("Stippled Alpha not supported yet.\n");
1884 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1886 if (state->render_states[WINED3D_RS_ANTIALIAS])
1887 FIXME("Antialias not supported yet.\n");
1890 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1892 if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
1893 FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
1894 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
1897 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1899 if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
1900 FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
1901 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
1904 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1906 union {
1907 DWORD d;
1908 float f;
1909 } tmpvalue;
1910 tmpvalue.f = 1.0f;
1912 if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
1914 static BOOL displayed = FALSE;
1916 tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
1917 if(!displayed)
1918 FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
1920 displayed = TRUE;
1924 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1926 if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
1927 FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
1928 state->render_states[WINED3D_RS_POSITIONDEGREE]);
1931 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1933 if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
1934 FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
1935 state->render_states[WINED3D_RS_NORMALDEGREE]);
1938 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1940 if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
1941 FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
1942 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
1945 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1947 union {
1948 DWORD d;
1949 float f;
1950 } zmin, zmax;
1952 const struct wined3d_gl_info *gl_info = context->gl_info;
1954 if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
1956 zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
1957 zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
1959 /* If zmin is larger than zmax INVALID_VALUE error is generated.
1960 * In d3d9 test is not performed in this case*/
1961 if (zmin.f <= zmax.f)
1963 gl_info->gl_ops.gl.p_glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
1964 checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
1965 GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
1966 checkGLcall("glDepthBoundsEXT(...)");
1968 else
1970 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1971 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1974 else
1976 gl_info->gl_ops.gl.p_glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
1977 checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
1980 state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
1983 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1985 if (state->render_states[WINED3D_RS_WRAPU])
1986 FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
1989 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1991 if (state->render_states[WINED3D_RS_WRAPV])
1992 FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
1995 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
1997 if (state->render_states[WINED3D_RS_MONOENABLE])
1998 FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
2001 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2003 if (state->render_states[WINED3D_RS_ROP2])
2004 FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
2007 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2009 if (state->render_states[WINED3D_RS_PLANEMASK])
2010 FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
2013 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2015 if (state->render_states[WINED3D_RS_SUBPIXEL])
2016 FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
2019 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2021 if (state->render_states[WINED3D_RS_SUBPIXELX])
2022 FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
2025 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2027 if (state->render_states[WINED3D_RS_STIPPLEENABLE])
2028 FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
2031 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2033 if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
2034 FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
2037 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2039 if (state->render_states[WINED3D_RS_ANISOTROPY])
2040 FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
2043 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2045 if (state->render_states[WINED3D_RS_FLUSHBATCH])
2046 FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
2049 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2051 if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
2052 FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
2055 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2057 if (state->render_states[WINED3D_RS_EXTENTS])
2058 FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
2061 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2063 if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
2064 FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
2067 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
2069 if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
2070 FIXME("Software vertex processing not implemented.\n");
2073 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
2074 /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
2075 * input should be used for all input components. The WINED3DTA_COMPLEMENT
2076 * flag specifies the complement of the input should be used. */
2077 BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
2078 BOOL complement = arg & WINED3DTA_COMPLEMENT;
2080 /* Calculate the operand */
2081 if (complement) {
2082 if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
2083 else *operand = GL_ONE_MINUS_SRC_COLOR;
2084 } else {
2085 if (from_alpha) *operand = GL_SRC_ALPHA;
2086 else *operand = GL_SRC_COLOR;
2089 /* Calculate the source */
2090 switch (arg & WINED3DTA_SELECTMASK) {
2091 case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
2092 case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
2093 case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
2094 case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
2095 case WINED3DTA_SPECULAR:
2097 * According to the GL_ARB_texture_env_combine specs, SPECULAR is
2098 * 'Secondary color' and isn't supported until base GL supports it
2099 * There is no concept of temp registers as far as I can tell
2101 FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
2102 *source = GL_TEXTURE;
2103 break;
2104 default:
2105 FIXME("Unrecognized texture arg %#x\n", arg);
2106 *source = GL_TEXTURE;
2107 break;
2111 /* Setup the texture operations texture stage states */
2112 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
2113 BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
2115 GLenum src1, src2, src3;
2116 GLenum opr1, opr2, opr3;
2117 GLenum comb_target;
2118 GLenum src0_target, src1_target, src2_target;
2119 GLenum opr0_target, opr1_target, opr2_target;
2120 GLenum scal_target;
2121 GLenum opr=0, invopr, src3_target, opr3_target;
2122 BOOL Handled = FALSE;
2124 TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
2126 /* This is called by a state handler which has the gl lock held and a context for the thread */
2128 /* Note: Operations usually involve two ars, src0 and src1 and are operations of
2129 the form (a1 <operation> a2). However, some of the more complex operations
2130 take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
2131 in a third parameter called a0. Therefore these are operations of the form
2132 a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
2134 However, below we treat the new (a0) parameter as src2/opr2, so in the actual
2135 functions below, expect their syntax to differ slightly to those listed in the
2136 manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
2137 This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */
2139 if (isAlpha)
2141 comb_target = GL_COMBINE_ALPHA;
2142 src0_target = GL_SOURCE0_ALPHA;
2143 src1_target = GL_SOURCE1_ALPHA;
2144 src2_target = GL_SOURCE2_ALPHA;
2145 opr0_target = GL_OPERAND0_ALPHA;
2146 opr1_target = GL_OPERAND1_ALPHA;
2147 opr2_target = GL_OPERAND2_ALPHA;
2148 scal_target = GL_ALPHA_SCALE;
2150 else
2152 comb_target = GL_COMBINE_RGB;
2153 src0_target = GL_SOURCE0_RGB;
2154 src1_target = GL_SOURCE1_RGB;
2155 src2_target = GL_SOURCE2_RGB;
2156 opr0_target = GL_OPERAND0_RGB;
2157 opr1_target = GL_OPERAND1_RGB;
2158 opr2_target = GL_OPERAND2_RGB;
2159 scal_target = GL_RGB_SCALE;
2162 /* If a texture stage references an invalid texture unit the stage just
2163 * passes through the result from the previous stage */
2164 if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
2166 arg1 = WINED3DTA_CURRENT;
2167 op = WINED3D_TOP_SELECT_ARG1;
2170 if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
2172 get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
2173 } else {
2174 get_src_and_opr(arg1, isAlpha, &src1, &opr1);
2176 get_src_and_opr(arg2, isAlpha, &src2, &opr2);
2177 get_src_and_opr(arg3, isAlpha, &src3, &opr3);
2179 TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
2181 Handled = TRUE; /* Assume will be handled */
2183 /* Other texture operations require special extensions: */
2184 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
2186 if (isAlpha) {
2187 opr = GL_SRC_ALPHA;
2188 invopr = GL_ONE_MINUS_SRC_ALPHA;
2189 src3_target = GL_SOURCE3_ALPHA_NV;
2190 opr3_target = GL_OPERAND3_ALPHA_NV;
2191 } else {
2192 opr = GL_SRC_COLOR;
2193 invopr = GL_ONE_MINUS_SRC_COLOR;
2194 src3_target = GL_SOURCE3_RGB_NV;
2195 opr3_target = GL_OPERAND3_RGB_NV;
2197 switch (op)
2199 case WINED3D_TOP_DISABLE: /* Only for alpha */
2200 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2201 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2202 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
2203 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2204 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2205 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2206 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2207 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2208 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2209 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2210 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2211 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2212 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2213 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2214 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2215 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2216 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2217 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2218 break;
2220 case WINED3D_TOP_SELECT_ARG1: /* = a1 * 1 + 0 * 0 */
2221 case WINED3D_TOP_SELECT_ARG2: /* = a2 * 1 + 0 * 0 */
2222 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2223 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2224 if (op == WINED3D_TOP_SELECT_ARG1)
2226 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2227 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2228 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2229 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2231 else
2233 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2234 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2235 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2236 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2238 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2239 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2240 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2241 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2242 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2243 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
2244 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2245 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2246 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2247 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2248 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2249 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2250 break;
2252 case WINED3D_TOP_MODULATE:
2253 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2254 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2255 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2256 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2257 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2258 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2259 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2260 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2261 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2262 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2263 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2264 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2265 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2266 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2267 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2268 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2269 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2270 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2271 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2272 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2273 break;
2274 case WINED3D_TOP_MODULATE_2X:
2275 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2276 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2277 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2278 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2279 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2280 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2281 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2282 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2283 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2284 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2285 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2286 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2287 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2288 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2289 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2290 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2291 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2292 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2293 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2294 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2295 break;
2296 case WINED3D_TOP_MODULATE_4X:
2297 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2298 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2299 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2300 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2301 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2302 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2303 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2304 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2305 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2306 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2307 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
2308 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2309 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2310 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2311 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2312 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2313 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2314 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
2315 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2316 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2317 break;
2319 case WINED3D_TOP_ADD:
2320 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2321 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2322 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2323 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2324 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2325 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2326 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2327 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2328 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2329 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2330 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2331 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2332 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2333 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2334 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2335 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2336 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2337 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2338 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2339 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2340 break;
2342 case WINED3D_TOP_ADD_SIGNED:
2343 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2344 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2345 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2346 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2347 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2348 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2349 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2350 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2351 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2352 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2353 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2354 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2355 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2356 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2357 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2358 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2359 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2360 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2361 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2362 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2363 break;
2365 case WINED3D_TOP_ADD_SIGNED_2X:
2366 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2367 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2368 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2369 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2370 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2371 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2372 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2373 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2374 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2375 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2376 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2377 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2378 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2379 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2380 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2381 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2382 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2383 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2384 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2385 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2386 break;
2388 case WINED3D_TOP_ADD_SMOOTH:
2389 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2390 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2391 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2392 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2393 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2394 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2395 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2396 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2397 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2398 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2399 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2400 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2401 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2402 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2403 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2404 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2405 switch (opr1) {
2406 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2407 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2408 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2409 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2411 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2412 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2413 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2414 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2415 break;
2417 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2418 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2419 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2420 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2421 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2422 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2423 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2424 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
2425 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
2426 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2427 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2428 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2429 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2430 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2431 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2432 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
2433 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
2434 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2435 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2436 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2437 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2438 break;
2439 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2440 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2441 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2442 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2443 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2444 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2445 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2446 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
2447 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
2448 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2449 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2450 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2451 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2452 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2453 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2454 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2455 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2456 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2457 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2458 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2459 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2460 break;
2461 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2462 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2463 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2464 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2465 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2466 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2467 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2468 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
2469 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
2470 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2471 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2472 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2473 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2474 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2475 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2476 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
2477 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
2478 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2479 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2480 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2481 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2482 break;
2483 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2484 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2485 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2486 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2487 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2488 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2489 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2490 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2491 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2492 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2493 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2494 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2495 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2496 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2497 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2498 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
2499 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
2500 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
2501 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
2502 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2503 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2504 break;
2505 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2506 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2507 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
2508 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */
2509 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2510 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2511 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */
2512 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2513 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2514 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2515 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2516 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */
2517 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2518 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2519 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */
2520 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2521 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2522 switch (opr) {
2523 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2524 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2526 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2527 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2528 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2529 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2530 break;
2531 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2532 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2533 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2534 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2535 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2536 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2537 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2538 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2539 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2540 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2541 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2542 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2543 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2544 switch (opr1) {
2545 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2546 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2548 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2549 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2550 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2551 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2552 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2553 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2554 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2555 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2556 break;
2557 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
2558 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2559 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2560 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2561 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2562 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2563 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2564 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2565 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2566 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2567 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2568 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2569 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2570 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2571 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2572 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
2573 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
2574 switch (opr1) {
2575 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2576 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2577 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2578 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2580 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
2581 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
2582 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2583 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2584 break;
2585 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
2586 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2587 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2588 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2589 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2590 switch (opr1) {
2591 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2592 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2593 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2594 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2596 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2597 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2598 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2599 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2600 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2601 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2602 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2603 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
2604 switch (opr1) {
2605 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2606 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2608 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
2609 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
2610 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
2611 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
2612 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
2613 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
2614 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2615 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2616 break;
2617 case WINED3D_TOP_MULTIPLY_ADD:
2618 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2619 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2620 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
2621 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2622 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
2623 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2624 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
2625 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
2626 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
2627 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
2628 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
2629 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2630 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
2631 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2632 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
2633 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
2634 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
2635 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
2636 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2637 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2638 break;
2640 case WINED3D_TOP_BUMPENVMAP:
2641 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
2642 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
2644 default:
2645 Handled = FALSE;
2647 if (Handled)
2649 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
2650 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
2652 return;
2654 } /* GL_NV_texture_env_combine4 */
2656 Handled = TRUE; /* Again, assume handled */
2657 switch (op) {
2658 case WINED3D_TOP_DISABLE: /* Only for alpha */
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, GL_PREVIOUS_EXT);
2662 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
2663 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
2664 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
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_ARG1:
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, src1);
2672 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2673 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2674 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
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_SELECT_ARG2:
2679 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
2680 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
2681 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
2682 checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
2683 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
2684 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
2685 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2686 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2687 break;
2688 case WINED3D_TOP_MODULATE:
2689 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2690 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2691 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2692 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2693 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2694 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2695 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2696 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2697 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2698 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2699 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2700 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2701 break;
2702 case WINED3D_TOP_MODULATE_2X:
2703 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2704 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2705 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2706 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2707 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2708 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2709 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2710 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2711 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2712 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2713 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2714 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2715 break;
2716 case WINED3D_TOP_MODULATE_4X:
2717 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
2718 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
2719 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2720 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2721 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2722 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2723 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2724 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2725 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2726 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2727 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
2728 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
2729 break;
2730 case WINED3D_TOP_ADD:
2731 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
2732 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
2733 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2734 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2735 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2736 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2737 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2738 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2739 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2740 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2741 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2742 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2743 break;
2744 case WINED3D_TOP_ADD_SIGNED:
2745 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2746 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2747 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2748 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2749 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2750 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2751 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2752 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2753 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2754 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2755 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2756 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2757 break;
2758 case WINED3D_TOP_ADD_SIGNED_2X:
2759 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
2760 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
2761 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2762 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2763 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2764 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2765 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2766 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2767 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2768 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2769 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
2770 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
2771 break;
2772 case WINED3D_TOP_SUBTRACT:
2773 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
2775 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
2776 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
2777 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2778 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2779 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2780 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2781 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2782 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2783 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2784 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2785 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2786 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2787 } else {
2788 FIXME("This version of opengl does not support GL_SUBTRACT\n");
2790 break;
2792 case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
2793 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2794 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2795 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2796 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2797 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2798 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2799 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2800 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2801 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2802 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2803 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
2804 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
2805 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2806 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2807 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2808 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2809 break;
2810 case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
2811 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2812 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2813 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2814 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2815 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2816 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2817 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2818 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2819 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2820 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2821 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
2822 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
2823 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2824 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2825 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2826 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2827 break;
2828 case WINED3D_TOP_BLEND_FACTOR_ALPHA:
2829 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2830 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2831 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2832 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2833 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2834 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2835 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2836 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2837 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2838 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2839 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
2840 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
2841 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2842 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2843 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2844 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2845 break;
2846 case WINED3D_TOP_BLEND_CURRENT_ALPHA:
2847 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2848 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2849 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2850 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2851 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2852 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2853 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2854 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2855 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2856 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2857 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
2858 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
2859 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
2860 checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
2861 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2862 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2863 break;
2864 case WINED3D_TOP_DOTPRODUCT3:
2865 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
2867 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
2868 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
2870 else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
2872 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
2873 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
2874 } else {
2875 FIXME("This version of opengl does not support GL_DOT3\n");
2877 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2878 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2879 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2880 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2881 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2882 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2883 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2884 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2885 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2886 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2887 break;
2888 case WINED3D_TOP_LERP:
2889 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
2890 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
2891 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2892 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2893 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2894 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2895 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
2896 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
2897 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
2898 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
2899 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
2900 checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
2901 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
2902 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
2903 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2904 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2905 break;
2906 case WINED3D_TOP_ADD_SMOOTH:
2907 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2909 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2910 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2911 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2912 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2913 switch (opr1) {
2914 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
2915 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
2916 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2917 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2919 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2920 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2921 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2922 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2923 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2924 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2925 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2926 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2927 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2928 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2929 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2930 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2931 } else
2932 Handled = FALSE;
2933 break;
2934 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
2935 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2937 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2938 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2939 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
2940 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
2941 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
2942 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
2943 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2944 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2945 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2946 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2947 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2948 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2949 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2950 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2951 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2952 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2953 } else
2954 Handled = FALSE;
2955 break;
2956 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
2957 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2959 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2960 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2961 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2962 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2963 switch (opr1) {
2964 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2965 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2966 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2967 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2969 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
2970 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
2971 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2972 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2973 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
2974 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
2975 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
2976 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
2977 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
2978 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
2979 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
2980 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
2981 } else
2982 Handled = FALSE;
2983 break;
2984 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
2985 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
2987 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
2988 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
2989 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
2990 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
2991 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
2992 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
2993 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
2994 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
2995 switch (opr1) {
2996 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
2997 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
2998 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
2999 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3001 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
3002 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
3003 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3004 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3005 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3006 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3007 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3008 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3009 } else
3010 Handled = FALSE;
3011 break;
3012 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3013 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3015 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3016 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3017 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3018 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3019 switch (opr1) {
3020 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3021 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3022 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3023 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3025 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3026 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3027 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3028 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3029 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
3030 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
3031 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3032 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3033 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3034 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3035 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3036 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3037 } else
3038 Handled = FALSE;
3039 break;
3040 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3041 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3043 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3044 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3045 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3046 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3047 switch (opr1) {
3048 case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
3049 case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
3050 case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3051 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3053 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
3054 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
3055 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
3056 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
3057 switch (opr1) {
3058 case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
3059 case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3060 case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
3061 case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
3063 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
3064 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
3065 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3066 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3067 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3068 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3069 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3070 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3071 } else
3072 Handled = FALSE;
3073 break;
3074 case WINED3D_TOP_MULTIPLY_ADD:
3075 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
3077 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
3078 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
3079 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
3080 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
3081 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
3082 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
3083 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
3084 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
3085 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
3086 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
3087 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
3088 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
3089 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
3090 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
3091 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
3092 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
3093 } else
3094 Handled = FALSE;
3095 break;
3096 case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
3097 case WINED3D_TOP_BUMPENVMAP:
3098 if (gl_info->supported[NV_TEXTURE_SHADER2])
3100 /* Technically texture shader support without register combiners is possible, but not expected to occur
3101 * on real world cards, so for now a fixme should be enough
3103 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
3105 default:
3106 Handled = FALSE;
3109 if (Handled) {
3110 BOOL combineOK = TRUE;
3111 if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
3113 DWORD op2;
3115 if (isAlpha)
3116 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
3117 else
3118 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
3120 /* Note: If COMBINE4 in effect can't go back to combine! */
3121 switch (op2)
3123 case WINED3D_TOP_ADD_SMOOTH:
3124 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
3125 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
3126 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
3127 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
3128 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
3129 case WINED3D_TOP_MULTIPLY_ADD:
3130 /* Ignore those implemented in both cases */
3131 switch (op)
3133 case WINED3D_TOP_SELECT_ARG1:
3134 case WINED3D_TOP_SELECT_ARG2:
3135 combineOK = FALSE;
3136 Handled = FALSE;
3137 break;
3138 default:
3139 FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
3140 return;
3145 if (combineOK)
3147 gl_info->gl_ops.gl.p_glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
3148 checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
3150 return;
3154 /* After all the extensions, if still unhandled, report fixme */
3155 FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
3159 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3161 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3162 const struct wined3d_device *device = context->swapchain->device;
3163 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3164 DWORD mapped_stage = device->texUnitMap[stage];
3165 const struct wined3d_gl_info *gl_info = context->gl_info;
3167 TRACE("Setting color op for stage %d\n", stage);
3169 /* Using a pixel shader? Don't care for anything here, the shader applying does it */
3170 if (use_ps(state)) return;
3172 if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
3174 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3176 if (tex_used && mapped_stage >= gl_info->limits.textures)
3178 FIXME("Attempt to enable unsupported stage!\n");
3179 return;
3181 context_active_texture(context, gl_info, mapped_stage);
3184 if (stage >= state->lowest_disabled_stage)
3186 TRACE("Stage disabled\n");
3187 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3189 /* Disable everything here */
3190 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_2D);
3191 checkGLcall("glDisable(GL_TEXTURE_2D)");
3192 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_3D);
3193 checkGLcall("glDisable(GL_TEXTURE_3D)");
3194 if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
3196 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_CUBE_MAP_ARB);
3197 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
3199 if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
3201 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_RECTANGLE_ARB);
3202 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
3205 /* All done */
3206 return;
3209 /* The sampler will also activate the correct texture dimensions, so no
3210 * need to do it here if the sampler for this stage is dirty. */
3211 if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
3212 texture_activate_dimensions(state->textures[stage], gl_info);
3214 set_tex_op(gl_info, state, FALSE, stage,
3215 state->texture_states[stage][WINED3D_TSS_COLOR_OP],
3216 state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
3217 state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
3218 state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
3221 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3223 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3224 const struct wined3d_device *device = context->swapchain->device;
3225 BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
3226 DWORD mapped_stage = device->texUnitMap[stage];
3227 const struct wined3d_gl_info *gl_info = context->gl_info;
3228 DWORD op, arg1, arg2, arg0;
3230 TRACE("Setting alpha op for stage %d\n", stage);
3231 /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
3232 if (mapped_stage != WINED3D_UNMAPPED_STAGE)
3234 if (tex_used && mapped_stage >= gl_info->limits.textures)
3236 FIXME("Attempt to enable unsupported stage!\n");
3237 return;
3239 context_active_texture(context, gl_info, mapped_stage);
3242 op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
3243 arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
3244 arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
3245 arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
3247 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
3249 struct wined3d_texture *texture = state->textures[0];
3250 GLenum texture_dimensions = texture->target;
3252 if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
3254 struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
3256 if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
3258 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
3259 * properly. On the other hand applications can still use texture combiners apparently. This code
3260 * takes care that apps cannot remove the texture's alpha channel entirely.
3262 * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
3263 * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
3264 * and alpha component of diffuse color to draw things like translucent text and perform other
3265 * blending effects.
3267 * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
3268 * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
3269 * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
3270 * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
3271 * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
3272 * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
3273 * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
3274 * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
3275 * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
3276 * alpha.
3278 * What to do with multitexturing? So far no app has been found that uses color keying with
3279 * multitexturing */
3280 if (op == WINED3D_TOP_DISABLE)
3282 arg1 = WINED3DTA_TEXTURE;
3283 op = WINED3D_TOP_SELECT_ARG1;
3285 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
3287 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3289 arg2 = WINED3DTA_TEXTURE;
3290 op = WINED3D_TOP_MODULATE;
3292 else arg1 = WINED3DTA_TEXTURE;
3294 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
3296 if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
3298 arg1 = WINED3DTA_TEXTURE;
3299 op = WINED3D_TOP_MODULATE;
3301 else arg2 = WINED3DTA_TEXTURE;
3307 /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
3308 * this if block here, and the other code(color keying, texture unit selection) are the same
3310 TRACE("Setting alpha op for stage %d\n", stage);
3311 if (gl_info->supported[NV_REGISTER_COMBINERS])
3313 set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
3314 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
3316 else
3318 set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
3322 static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3324 DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3325 const struct wined3d_device *device = context->swapchain->device;
3326 const struct wined3d_gl_info *gl_info = context->gl_info;
3327 DWORD mapped_stage = device->texUnitMap[texUnit];
3328 BOOL generated;
3329 int coordIdx;
3331 /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
3332 if (use_vs(state) || isStateDirty(context, STATE_VDECL))
3334 TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
3335 return;
3338 if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
3339 if (mapped_stage >= gl_info->limits.textures) return;
3341 context_active_texture(context, gl_info, mapped_stage);
3342 generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
3343 coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
3345 set_texture_matrix(gl_info, &state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
3346 state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
3347 generated, context->last_was_rhw,
3348 device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
3349 ? device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
3350 : WINED3DFMT_UNKNOWN,
3351 device->frag_pipe->ffp_proj_control);
3353 /* The sampler applying function calls us if this changes */
3354 if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
3356 if(generated) {
3357 FIXME("Non-power2 texture being used with generated texture coords\n");
3359 /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
3360 fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
3361 if (!use_ps(state))
3363 TRACE("Non power two matrix multiply fixup\n");
3364 gl_info->gl_ops.gl.p_glMultMatrixf(state->textures[texUnit]->pow2_matrix);
3369 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
3371 unsigned int texture_idx;
3373 for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
3375 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
3376 gl_info->gl_ops.gl.p_glDisableClientState(GL_TEXTURE_COORD_ARRAY);
3380 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
3381 GLuint *curVBO, const struct wined3d_state *state)
3383 const struct wined3d_device *device = context->swapchain->device;
3384 const struct wined3d_gl_info *gl_info = context->gl_info;
3385 unsigned int mapped_stage = 0;
3386 unsigned int textureNo = 0;
3388 for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
3390 int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
3392 mapped_stage = device->texUnitMap[textureNo];
3393 if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
3395 if (mapped_stage >= gl_info->limits.texture_coords)
3397 FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
3398 continue;
3401 if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
3403 const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
3405 TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
3406 textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
3408 if (*curVBO != e->data.buffer_object)
3410 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
3411 checkGLcall("glBindBufferARB");
3412 *curVBO = e->data.buffer_object;
3415 GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
3416 checkGLcall("glClientActiveTextureARB");
3418 /* The coords to supply depend completely on the fvf / vertex shader */
3419 gl_info->gl_ops.gl.p_glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
3420 e->data.addr + state->load_base_vertex_index * e->stride);
3421 gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
3423 else
3425 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
3428 if (gl_info->supported[NV_REGISTER_COMBINERS])
3430 /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
3431 for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
3433 GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
3437 checkGLcall("loadTexCoords");
3440 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3442 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3443 const struct wined3d_device *device = context->swapchain->device;
3444 static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
3445 static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
3446 static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
3447 static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
3448 const struct wined3d_gl_info *gl_info = context->gl_info;
3449 DWORD mapped_stage = device->texUnitMap[stage];
3451 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3453 TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
3454 return;
3457 if (mapped_stage >= gl_info->limits.fragment_samplers)
3459 WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
3460 return;
3462 context_active_texture(context, gl_info, mapped_stage);
3464 /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
3466 * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
3467 * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
3468 * means use the vertex position (camera-space) as the input texture coordinates
3469 * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
3470 * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
3471 * to the TEXCOORDINDEX value
3473 switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
3475 case WINED3DTSS_TCI_PASSTHRU:
3476 /* Use the specified texture coordinates contained within the
3477 * vertex format. This value resolves to zero. */
3478 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3479 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3480 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3481 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3482 checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
3483 break;
3485 case WINED3DTSS_TCI_CAMERASPACEPOSITION:
3486 /* CameraSpacePosition means use the vertex position, transformed to camera space,
3487 * as the input texture coordinates for this stage's texture transformation. This
3488 * equates roughly to EYE_LINEAR */
3490 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3491 gl_info->gl_ops.gl.p_glPushMatrix();
3492 gl_info->gl_ops.gl.p_glLoadIdentity();
3493 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3494 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3495 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3496 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3497 gl_info->gl_ops.gl.p_glPopMatrix();
3498 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
3500 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3501 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3502 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
3503 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
3505 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3506 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3507 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3508 checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
3510 break;
3512 case WINED3DTSS_TCI_CAMERASPACENORMAL:
3513 /* Note that NV_TEXGEN_REFLECTION support is implied when
3514 * ARB_TEXTURE_CUBE_MAP is supported */
3515 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3517 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
3518 break;
3521 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3522 gl_info->gl_ops.gl.p_glPushMatrix();
3523 gl_info->gl_ops.gl.p_glLoadIdentity();
3524 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3525 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3526 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3527 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3528 gl_info->gl_ops.gl.p_glPopMatrix();
3529 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
3531 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3532 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3533 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
3534 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
3536 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3537 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3538 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3539 checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
3541 break;
3543 case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
3544 /* Note that NV_TEXGEN_REFLECTION support is implied when
3545 * ARB_TEXTURE_CUBE_MAP is supported */
3546 if (!gl_info->supported[NV_TEXGEN_REFLECTION])
3548 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
3549 break;
3552 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3553 gl_info->gl_ops.gl.p_glPushMatrix();
3554 gl_info->gl_ops.gl.p_glLoadIdentity();
3555 gl_info->gl_ops.gl.p_glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
3556 gl_info->gl_ops.gl.p_glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
3557 gl_info->gl_ops.gl.p_glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
3558 gl_info->gl_ops.gl.p_glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
3559 gl_info->gl_ops.gl.p_glPopMatrix();
3560 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
3562 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3563 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3564 gl_info->gl_ops.gl.p_glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
3565 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
3567 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3568 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3569 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_R);
3570 checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
3572 break;
3574 case WINED3DTSS_TCI_SPHEREMAP:
3575 gl_info->gl_ops.gl.p_glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3576 gl_info->gl_ops.gl.p_glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
3577 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
3579 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_S);
3580 gl_info->gl_ops.gl.p_glEnable(GL_TEXTURE_GEN_T);
3581 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3582 checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
3584 break;
3586 default:
3587 FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
3588 state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
3589 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_S);
3590 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_T);
3591 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_R);
3592 gl_info->gl_ops.gl.p_glDisable(GL_TEXTURE_GEN_Q);
3593 checkGLcall("Disable texgen.");
3595 break;
3598 /* Update the texture matrix. */
3599 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
3600 transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3602 if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
3604 /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
3605 * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
3606 * and do all the things linked to it
3607 * TODO: Tidy that up to reload only the arrays of the changed unit
3609 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
3611 unload_tex_coords(gl_info);
3612 load_tex_coords(context, &device->strided_streams, &curVBO, state);
3616 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3618 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3619 const struct wined3d_shader *ps = state->pixel_shader;
3621 if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
3623 /* The pixel shader has to know the luminance scale. Do a constants
3624 * update if it isn't scheduled anyway. */
3625 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3626 && !isStateDirty(context, STATE_PIXELSHADER))
3627 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3631 static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3633 const DWORD sampler = state_id - STATE_SAMPLER(0);
3634 const struct wined3d_texture *texture = state->textures[sampler];
3636 TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
3638 if(!texture) return;
3639 /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
3640 * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
3641 * scaling is reapplied or removed, the texture matrix has to be reapplied
3643 * The mapped stage is already active because the sampler() function below, which is part of the
3644 * misc pipeline
3646 if (sampler < MAX_TEXTURES)
3648 const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
3650 if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
3652 const struct wined3d_device *device = context->swapchain->device;
3654 if (texIsPow2)
3655 context->lastWasPow2Texture |= 1 << sampler;
3656 else
3657 context->lastWasPow2Texture &= ~(1 << sampler);
3659 transform_texture(context, state,
3660 STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
3665 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3667 const struct wined3d_device *device = context->swapchain->device;
3668 DWORD sampler = state_id - STATE_SAMPLER(0);
3669 DWORD mapped_stage = device->texUnitMap[sampler];
3670 const struct wined3d_gl_info *gl_info = context->gl_info;
3671 union {
3672 float f;
3673 DWORD d;
3674 } tmpvalue;
3676 TRACE("Sampler: %d\n", sampler);
3677 /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
3678 * only has to bind textures and set the per texture states
3681 if (mapped_stage == WINED3D_UNMAPPED_STAGE)
3683 TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
3684 return;
3687 if (mapped_stage >= gl_info->limits.combined_samplers)
3689 return;
3691 context_active_texture(context, gl_info, mapped_stage);
3693 if (state->textures[sampler])
3695 struct wined3d_texture *texture = state->textures[sampler];
3696 BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
3698 texture->texture_ops->texture_bind(texture, context, srgb);
3699 wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
3701 if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
3703 tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
3704 gl_info->gl_ops.gl.p_glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
3705 GL_TEXTURE_LOD_BIAS_EXT, tmpvalue.f);
3706 checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
3709 if (!use_ps(state) && sampler < state->lowest_disabled_stage)
3711 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3713 /* If color keying is enabled update the alpha test, it
3714 * depends on the existence of a color key in stage 0. */
3715 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3719 /* Trigger shader constant reloading (for NP2 texcoord fixup) */
3720 if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
3721 device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
3723 else
3725 if (sampler < state->lowest_disabled_stage)
3727 /* TODO: What should I do with pixel shaders here ??? */
3728 if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
3730 /* If color keying is enabled update the alpha test, it
3731 * depends on the existence of a color key in stage 0. */
3732 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
3734 } /* Otherwise tex_colorop disables the stage */
3735 context_bind_texture(context, GL_NONE, 0);
3739 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3741 const struct wined3d_device *device = context->swapchain->device;
3742 BOOL use_vshader = use_vs(state);
3743 BOOL use_pshader = use_ps(state);
3744 unsigned int i;
3746 if (use_pshader)
3748 if (!context->last_was_pshader)
3750 /* Former draw without a pixel shader, some samplers may be
3751 * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
3752 * make sure to enable them. */
3753 for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
3755 if (!isStateDirty(context, STATE_SAMPLER(i)))
3756 sampler(context, state, STATE_SAMPLER(i));
3758 context->last_was_pshader = TRUE;
3760 else
3762 /* Otherwise all samplers were activated by the code above in
3763 * earlier draws, or by sampler() if a different texture was
3764 * bound. I don't have to do anything. */
3767 else
3769 /* Disabled the pixel shader - color ops weren't applied while it was
3770 * enabled, so re-apply them. */
3771 for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
3773 if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
3774 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
3776 context->last_was_pshader = FALSE;
3779 if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
3781 device->shader_backend->shader_select(context, use_pshader, use_vshader);
3783 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader))
3784 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
3788 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3790 DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
3791 const struct wined3d_shader *ps = state->pixel_shader;
3793 if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
3795 /* The pixel shader has to know the bump env matrix. Do a constants
3796 * update if it isn't scheduled anyway. */
3797 if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
3798 && !isStateDirty(context, STATE_PIXELSHADER))
3799 shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
3803 static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3805 const struct wined3d_gl_info *gl_info = context->gl_info;
3807 /* This function is called by transform_view below if the view matrix was changed too
3809 * Deliberately no check if the vertex declaration is dirty because the vdecl state
3810 * does not always update the world matrix, only on a switch between transformed
3811 * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
3812 * draw, but that should be rather rare and cheaper in total.
3814 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3815 checkGLcall("glMatrixMode");
3817 if (context->last_was_rhw)
3819 gl_info->gl_ops.gl.p_glLoadIdentity();
3820 checkGLcall("glLoadIdentity()");
3822 else
3824 /* In the general case, the view matrix is the identity matrix */
3825 if (context->swapchain->device->view_ident)
3827 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3828 checkGLcall("glLoadMatrixf");
3830 else
3832 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3833 checkGLcall("glLoadMatrixf");
3834 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
3835 checkGLcall("glMultMatrixf");
3840 static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3842 const struct wined3d_gl_info *gl_info = context->gl_info;
3843 UINT index = state_id - STATE_CLIPPLANE(0);
3844 GLdouble plane[4];
3846 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.clipplanes)
3847 return;
3849 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3850 gl_info->gl_ops.gl.p_glPushMatrix();
3852 /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
3853 if (!use_vs(state))
3854 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3855 else
3856 /* With vertex shaders, clip planes are not transformed in Direct3D,
3857 * while in OpenGL they are still transformed by the model view matix. */
3858 gl_info->gl_ops.gl.p_glLoadIdentity();
3860 plane[0] = state->clip_planes[index].x;
3861 plane[1] = state->clip_planes[index].y;
3862 plane[2] = state->clip_planes[index].z;
3863 plane[3] = state->clip_planes[index].w;
3865 TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
3866 plane[0], plane[1], plane[2], plane[3]);
3867 gl_info->gl_ops.gl.p_glClipPlane(GL_CLIP_PLANE0 + index, plane);
3868 checkGLcall("glClipPlane");
3870 gl_info->gl_ops.gl.p_glPopMatrix();
3873 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3875 UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
3876 const struct wined3d_gl_info *gl_info = context->gl_info;
3877 GLenum glMat;
3879 TRACE("Setting world matrix %d\n", matrix);
3881 if (matrix >= gl_info->limits.blends)
3883 WARN("Unsupported blend matrix set\n");
3884 return;
3887 if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
3888 return;
3890 /* GL_MODELVIEW0_ARB: 0x1700
3891 * GL_MODELVIEW1_ARB: 0x850a
3892 * GL_MODELVIEW2_ARB: 0x8722
3893 * GL_MODELVIEW3_ARB: 0x8723
3894 * etc
3895 * GL_MODELVIEW31_ARB: 0x873f
3897 if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
3898 else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
3900 gl_info->gl_ops.gl.p_glMatrixMode(glMat);
3901 checkGLcall("glMatrixMode(glMat)");
3903 /* World matrix 0 is multiplied with the view matrix because d3d uses 3
3904 * matrices while gl uses only 2. To avoid weighting the view matrix
3905 * incorrectly it has to be multiplied into every GL modelview matrix. */
3906 if (context->swapchain->device->view_ident)
3908 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3909 checkGLcall("glLoadMatrixf");
3911 else
3913 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3914 checkGLcall("glLoadMatrixf");
3915 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
3916 checkGLcall("glMultMatrixf");
3920 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3922 enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
3923 static unsigned int once;
3925 if (f == WINED3D_VBF_DISABLE)
3926 return;
3928 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
3929 else WARN("Vertex blend flags %#x not supported.\n", f);
3932 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3934 enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
3935 struct wined3d_device *device = context->swapchain->device;
3936 const struct wined3d_gl_info *gl_info = context->gl_info;
3937 static unsigned int once;
3939 switch (val)
3941 case WINED3D_VBF_1WEIGHTS:
3942 case WINED3D_VBF_2WEIGHTS:
3943 case WINED3D_VBF_3WEIGHTS:
3944 gl_info->gl_ops.gl.p_glEnable(GL_VERTEX_BLEND_ARB);
3945 checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
3947 /* D3D adds one more matrix which has weight (1 - sum(weights)).
3948 * This is enabled at context creation with enabling
3949 * GL_WEIGHT_SUM_UNITY_ARB. */
3950 GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
3952 if (!device->vertexBlendUsed)
3954 unsigned int i;
3955 for (i = 1; i < gl_info->limits.blends; ++i)
3957 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
3958 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
3960 device->vertexBlendUsed = TRUE;
3962 break;
3964 case WINED3D_VBF_TWEENING:
3965 case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
3966 if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
3967 else WARN("Vertex blend flags %#x not supported.\n", val);
3968 /* Fall through. */
3969 case WINED3D_VBF_DISABLE:
3970 gl_info->gl_ops.gl.p_glDisable(GL_VERTEX_BLEND_ARB);
3971 checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
3972 break;
3976 static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
3978 const struct wined3d_gl_info *gl_info = context->gl_info;
3979 const struct wined3d_light_info *light = NULL;
3980 unsigned int k;
3982 /* If we are changing the View matrix, reset the light and clipping planes to the new view
3983 * NOTE: We have to reset the positions even if the light/plane is not currently
3984 * enabled, since the call to enable it will not reset the position.
3985 * NOTE2: Apparently texture transforms do NOT need reapplying
3988 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
3989 checkGLcall("glMatrixMode(GL_MODELVIEW)");
3990 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
3991 checkGLcall("glLoadMatrixf(...)");
3993 /* Reset lights. TODO: Call light apply func */
3994 for (k = 0; k < gl_info->limits.lights; ++k)
3996 if (!(light = state->lights[k]))
3997 continue;
3998 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
3999 checkGLcall("glLightfv posn");
4000 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
4001 checkGLcall("glLightfv dirn");
4004 /* Reset Clipping Planes */
4005 for (k = 0; k < gl_info->limits.clipplanes; ++k)
4007 if (!isStateDirty(context, STATE_CLIPPLANE(k)))
4008 clipplane(context, state, STATE_CLIPPLANE(k));
4011 if (context->last_was_rhw)
4013 gl_info->gl_ops.gl.p_glLoadIdentity();
4014 checkGLcall("glLoadIdentity()");
4015 /* No need to update the world matrix, the identity is fine */
4016 return;
4019 /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
4020 * No need to do it here if the state is scheduled for update. */
4021 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4022 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4024 /* Avoid looping over a number of matrices if the app never used the functionality */
4025 if (context->swapchain->device->vertexBlendUsed)
4027 for (k = 1; k < gl_info->limits.blends; ++k)
4029 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
4030 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
4035 static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4037 const struct wined3d_gl_info *gl_info = context->gl_info;
4039 gl_info->gl_ops.gl.p_glMatrixMode(GL_PROJECTION);
4040 checkGLcall("glMatrixMode(GL_PROJECTION)");
4042 /* There are a couple of additional things we have to take into account
4043 * here besides the projection transformation itself:
4044 * - We need to flip along the y-axis in case of offscreen rendering.
4045 * - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
4046 * - D3D coordinates refer to pixel centers while GL coordinates refer
4047 * to pixel corners.
4048 * - D3D has a top-left filling convention. We need to maintain this
4049 * even after the y-flip mentioned above.
4050 * In order to handle the last two points, we translate by
4051 * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
4052 * translating slightly less than half a pixel. We want the difference to
4053 * be large enough that it doesn't get lost due to rounding inside the
4054 * driver, but small enough to prevent it from interfering with any
4055 * anti-aliasing. */
4057 if (context->last_was_rhw)
4059 /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
4060 double x = state->viewport.x;
4061 double y = state->viewport.y;
4062 double w = state->viewport.width;
4063 double h = state->viewport.height;
4064 double x_scale = 2.0 / w;
4065 double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
4066 double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
4067 double y_offset = context->render_offscreen
4068 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
4069 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
4070 const GLdouble projection[] =
4072 x_scale, 0.0, 0.0, 0.0,
4073 0.0, y_scale, 0.0, 0.0,
4074 0.0, 0.0, 2.0, 0.0,
4075 x_offset, y_offset, -1.0, 1.0,
4078 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4079 checkGLcall("glLoadMatrixd");
4081 else
4083 double y_scale = context->render_offscreen ? -1.0 : 1.0;
4084 double x_offset = (63.0 / 64.0) / state->viewport.width;
4085 double y_offset = context->render_offscreen
4086 ? (63.0 / 64.0) / state->viewport.height
4087 : -(63.0 / 64.0) / state->viewport.height;
4088 const GLdouble projection[] =
4090 1.0, 0.0, 0.0, 0.0,
4091 0.0, y_scale, 0.0, 0.0,
4092 0.0, 0.0, 2.0, 0.0,
4093 x_offset, y_offset, -1.0, 1.0,
4096 gl_info->gl_ops.gl.p_glLoadMatrixd(projection);
4097 checkGLcall("glLoadMatrixd");
4099 gl_info->gl_ops.gl.p_glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
4100 checkGLcall("glLoadMatrixf");
4104 /* This should match any arrays loaded in load_vertex_data.
4105 * TODO: Only load / unload arrays if we have to. */
4106 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
4108 gl_info->gl_ops.gl.p_glDisableClientState(GL_VERTEX_ARRAY);
4109 gl_info->gl_ops.gl.p_glDisableClientState(GL_NORMAL_ARRAY);
4110 gl_info->gl_ops.gl.p_glDisableClientState(GL_COLOR_ARRAY);
4111 if (gl_info->supported[EXT_SECONDARY_COLOR])
4112 gl_info->gl_ops.gl.p_glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4113 if (gl_info->supported[ARB_VERTEX_BLEND])
4114 gl_info->gl_ops.gl.p_glDisableClientState(GL_WEIGHT_ARRAY_ARB);
4115 unload_tex_coords(gl_info);
4118 static inline void unload_numbered_array(struct wined3d_context *context, int i)
4120 const struct wined3d_gl_info *gl_info = context->gl_info;
4122 GL_EXTCALL(glDisableVertexAttribArrayARB(i));
4123 checkGLcall("glDisableVertexAttribArrayARB(reg)");
4125 context->numbered_array_mask &= ~(1 << i);
4128 /* This should match any arrays loaded in loadNumberedArrays
4129 * TODO: Only load / unload arrays if we have to. */
4130 static void unload_numbered_arrays(struct wined3d_context *context)
4132 /* disable any attribs (this is the same for both GLSL and ARB modes) */
4133 int i;
4135 for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
4136 unload_numbered_array(context, i);
4140 static void load_numbered_arrays(struct wined3d_context *context,
4141 const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
4143 struct wined3d_device *device = context->swapchain->device;
4144 const struct wined3d_gl_info *gl_info = context->gl_info;
4145 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4146 int i;
4148 /* Default to no instancing */
4149 device->instancedDraw = FALSE;
4151 for (i = 0; i < MAX_ATTRIBS; i++)
4153 const struct wined3d_stream_state *stream;
4155 if (!(stream_info->use_map & (1 << i)))
4157 if (context->numbered_array_mask & (1 << i))
4158 unload_numbered_array(context, i);
4159 if (state->vertex_shader->reg_maps.input_registers & (1 << i))
4160 GL_EXTCALL(glVertexAttrib4fARB(i, 0.0f, 0.0f, 0.0f, 0.0f));
4161 continue;
4164 stream = &state->streams[stream_info->elements[i].stream_idx];
4166 /* Do not load instance data. It will be specified using glTexCoord by drawprim */
4167 if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
4169 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4170 device->instancedDraw = TRUE;
4171 continue;
4174 TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
4176 if (stream_info->elements[i].stride)
4178 if (curVBO != stream_info->elements[i].data.buffer_object)
4180 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
4181 checkGLcall("glBindBufferARB");
4182 curVBO = stream_info->elements[i].data.buffer_object;
4184 /* Use the VBO to find out if a vertex buffer exists, not the vb
4185 * pointer. vb can point to a user pointer data blob. In that case
4186 * curVBO will be 0. If there is a vertex buffer but no vbo we
4187 * won't be load converted attributes anyway. */
4188 GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
4189 stream_info->elements[i].format->gl_vtx_type,
4190 stream_info->elements[i].format->gl_normalized,
4191 stream_info->elements[i].stride, stream_info->elements[i].data.addr
4192 + state->load_base_vertex_index * stream_info->elements[i].stride));
4194 if (!(context->numbered_array_mask & (1 << i)))
4196 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
4197 context->numbered_array_mask |= (1 << i);
4200 else
4202 /* Stride = 0 means always the same values.
4203 * glVertexAttribPointerARB doesn't do that. Instead disable the
4204 * pointer and set up the attribute statically. But we have to
4205 * figure out the system memory address. */
4206 const BYTE *ptr = stream_info->elements[i].data.addr;
4207 if (stream_info->elements[i].data.buffer_object)
4209 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
4212 if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
4214 switch (stream_info->elements[i].format->id)
4216 case WINED3DFMT_R32_FLOAT:
4217 GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
4218 break;
4219 case WINED3DFMT_R32G32_FLOAT:
4220 GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
4221 break;
4222 case WINED3DFMT_R32G32B32_FLOAT:
4223 GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
4224 break;
4225 case WINED3DFMT_R32G32B32A32_FLOAT:
4226 GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
4227 break;
4229 case WINED3DFMT_R8G8B8A8_UINT:
4230 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4231 break;
4232 case WINED3DFMT_B8G8R8A8_UNORM:
4233 if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
4235 const DWORD *src = (const DWORD *)ptr;
4236 DWORD c = *src & 0xff00ff00;
4237 c |= (*src & 0xff0000) >> 16;
4238 c |= (*src & 0xff) << 16;
4239 GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
4240 break;
4242 /* else fallthrough */
4243 case WINED3DFMT_R8G8B8A8_UNORM:
4244 GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
4245 break;
4247 case WINED3DFMT_R16G16_SINT:
4248 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4249 break;
4250 case WINED3DFMT_R16G16B16A16_SINT:
4251 GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
4252 break;
4254 case WINED3DFMT_R16G16_SNORM:
4256 const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
4257 GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
4258 break;
4260 case WINED3DFMT_R16G16_UNORM:
4262 const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
4263 GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
4264 break;
4266 case WINED3DFMT_R16G16B16A16_SNORM:
4267 GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
4268 break;
4269 case WINED3DFMT_R16G16B16A16_UNORM:
4270 GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
4271 break;
4273 case WINED3DFMT_R10G10B10A2_UINT:
4274 FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
4275 /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
4276 break;
4277 case WINED3DFMT_R10G10B10A2_SNORM:
4278 FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
4279 /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
4280 break;
4282 case WINED3DFMT_R16G16_FLOAT:
4283 /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
4284 * byte float according to the IEEE standard
4286 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
4287 break;
4288 case WINED3DFMT_R16G16B16A16_FLOAT:
4289 FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
4290 break;
4292 default:
4293 ERR("Unexpected declaration in stride 0 attributes\n");
4294 break;
4299 checkGLcall("Loading numbered arrays");
4302 static void load_vertex_data(const struct wined3d_context *context,
4303 const struct wined3d_stream_info *si, const struct wined3d_state *state)
4305 struct wined3d_device *device = context->swapchain->device;
4306 const struct wined3d_gl_info *gl_info = context->gl_info;
4307 GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
4308 const struct wined3d_stream_info_element *e;
4310 TRACE("Using fast vertex array code\n");
4312 /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
4313 device->instancedDraw = FALSE;
4315 /* Blend Data ---------------------------------------------- */
4316 if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
4317 || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4319 e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
4321 if (gl_info->supported[ARB_VERTEX_BLEND])
4323 TRACE("Blend %u %p %u\n", e->format->component_count,
4324 e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
4326 gl_info->gl_ops.gl.p_glEnableClientState(GL_WEIGHT_ARRAY_ARB);
4327 checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
4329 GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
4331 if (curVBO != e->data.buffer_object)
4333 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4334 checkGLcall("glBindBufferARB");
4335 curVBO = e->data.buffer_object;
4338 TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
4339 e->format->gl_vtx_format,
4340 e->format->gl_vtx_type,
4341 e->stride,
4342 e->data.addr + state->load_base_vertex_index * e->stride);
4343 GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4344 e->data.addr + state->load_base_vertex_index * e->stride));
4346 checkGLcall("glWeightPointerARB");
4348 if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
4350 static BOOL warned;
4351 if (!warned)
4353 FIXME("blendMatrixIndices support\n");
4354 warned = TRUE;
4357 } else {
4358 /* TODO: support blends in drawStridedSlow
4359 * No need to write a FIXME here, this is done after the general vertex decl decoding
4361 WARN("unsupported blending in openGl\n");
4364 else
4366 if (gl_info->supported[ARB_VERTEX_BLEND])
4368 static const GLbyte one = 1;
4369 GL_EXTCALL(glWeightbvARB(1, &one));
4370 checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
4374 /* Point Size ----------------------------------------------*/
4375 if (si->use_map & (1 << WINED3D_FFP_PSIZE))
4377 /* no such functionality in the fixed function GL pipeline */
4378 TRACE("Cannot change ptSize here in openGl\n");
4379 /* TODO: Implement this function in using shaders if they are available */
4382 /* Vertex Pointers -----------------------------------------*/
4383 if (si->use_map & (1 << WINED3D_FFP_POSITION))
4385 e = &si->elements[WINED3D_FFP_POSITION];
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("glVertexPointer(%#x, %#x, %#x, %p);\n",
4395 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4396 e->data.addr + state->load_base_vertex_index * e->stride);
4397 gl_info->gl_ops.gl.p_glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4398 e->data.addr + state->load_base_vertex_index * e->stride);
4399 checkGLcall("glVertexPointer(...)");
4400 gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
4401 checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
4404 /* Normals -------------------------------------------------*/
4405 if (si->use_map & (1 << WINED3D_FFP_NORMAL))
4407 e = &si->elements[WINED3D_FFP_NORMAL];
4409 if (curVBO != e->data.buffer_object)
4411 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4412 checkGLcall("glBindBufferARB");
4413 curVBO = e->data.buffer_object;
4416 TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
4417 e->data.addr + state->load_base_vertex_index * e->stride);
4418 gl_info->gl_ops.gl.p_glNormalPointer(e->format->gl_vtx_type, e->stride,
4419 e->data.addr + state->load_base_vertex_index * e->stride);
4420 checkGLcall("glNormalPointer(...)");
4421 gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
4422 checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
4425 else
4427 gl_info->gl_ops.gl.p_glNormal3f(0, 0, 0);
4428 checkGLcall("glNormal3f(0, 0, 0)");
4431 /* Diffuse Colour --------------------------------------------*/
4432 if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
4434 e = &si->elements[WINED3D_FFP_DIFFUSE];
4436 if (curVBO != e->data.buffer_object)
4438 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4439 checkGLcall("glBindBufferARB");
4440 curVBO = e->data.buffer_object;
4443 TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
4444 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4445 e->data.addr + state->load_base_vertex_index * e->stride);
4446 gl_info->gl_ops.gl.p_glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
4447 e->data.addr + state->load_base_vertex_index * e->stride);
4448 checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
4449 gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
4450 checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
4453 else
4455 gl_info->gl_ops.gl.p_glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
4456 checkGLcall("glColor4f(1, 1, 1, 1)");
4459 /* Specular Colour ------------------------------------------*/
4460 if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
4462 TRACE("setting specular colour\n");
4464 e = &si->elements[WINED3D_FFP_SPECULAR];
4466 if (gl_info->supported[EXT_SECONDARY_COLOR])
4468 GLenum type = e->format->gl_vtx_type;
4469 GLint format = e->format->gl_vtx_format;
4471 if (curVBO != e->data.buffer_object)
4473 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
4474 checkGLcall("glBindBufferARB");
4475 curVBO = e->data.buffer_object;
4478 if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
4480 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
4481 * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
4482 * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
4483 * 4 component secondary colors use it
4485 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
4486 e->data.addr + state->load_base_vertex_index * e->stride);
4487 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
4488 e->data.addr + state->load_base_vertex_index * e->stride));
4489 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
4491 else
4493 switch(type)
4495 case GL_UNSIGNED_BYTE:
4496 TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
4497 e->data.addr + state->load_base_vertex_index * e->stride);
4498 GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
4499 e->data.addr + state->load_base_vertex_index * e->stride));
4500 checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
4501 break;
4503 default:
4504 FIXME("Add 4 component specular color pointers for type %x\n", type);
4505 /* Make sure that the right color component is dropped */
4506 TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
4507 e->data.addr + state->load_base_vertex_index * e->stride);
4508 GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
4509 e->data.addr + state->load_base_vertex_index * e->stride));
4510 checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
4513 gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
4514 checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
4516 else
4518 WARN("Specular colour is not supported in this GL implementation.\n");
4521 else
4523 if (gl_info->supported[EXT_SECONDARY_COLOR])
4525 GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
4526 checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
4528 else
4530 WARN("Specular colour is not supported in this GL implementation.\n");
4534 /* Texture coords -------------------------------------------*/
4535 load_tex_coords(context, si, &curVBO, state);
4538 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4540 const struct wined3d_device *device = context->swapchain->device;
4541 BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
4542 BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
4544 if (isStateDirty(context, STATE_VDECL)) return;
4545 if (context->numberedArraysLoaded && !load_numbered)
4547 unload_numbered_arrays(context);
4548 context->numberedArraysLoaded = FALSE;
4549 context->numbered_array_mask = 0;
4551 else if (context->namedArraysLoaded)
4553 unload_vertex_data(context->gl_info);
4554 context->namedArraysLoaded = FALSE;
4557 if (load_numbered)
4559 TRACE("Loading numbered arrays\n");
4560 load_numbered_arrays(context, &device->strided_streams, state);
4561 context->numberedArraysLoaded = TRUE;
4563 else if (load_named)
4565 TRACE("Loading vertex data\n");
4566 load_vertex_data(context, &device->strided_streams, state);
4567 context->namedArraysLoaded = TRUE;
4571 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4573 if (isStateDirty(context, STATE_STREAMSRC))
4574 return;
4575 streamsrc(context, state, STATE_STREAMSRC);
4578 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4580 const struct wined3d_device *device = context->swapchain->device;
4581 const struct wined3d_gl_info *gl_info = context->gl_info;
4582 BOOL useVertexShaderFunction = use_vs(state);
4583 BOOL usePixelShaderFunction = use_ps(state);
4584 BOOL updateFog = FALSE;
4585 BOOL transformed;
4586 BOOL wasrhw = context->last_was_rhw;
4587 unsigned int i;
4589 transformed = device->strided_streams.position_transformed;
4590 if (transformed != context->last_was_rhw && !useVertexShaderFunction)
4591 updateFog = TRUE;
4593 context->last_was_rhw = transformed;
4595 /* Don't have to apply the matrices when vertex shaders are used. When
4596 * vshaders are turned off this function will be called again anyway to
4597 * make sure they're properly set. */
4598 if (!useVertexShaderFunction)
4600 /* TODO: Move this mainly to the viewport state and only apply when
4601 * the vp has changed or transformed / untransformed was switched. */
4602 if (wasrhw != context->last_was_rhw
4603 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
4604 && !isStateDirty(context, STATE_VIEWPORT))
4605 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4606 /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
4607 * mode.
4609 * If a vertex shader is used, the world matrix changed and then vertex shader unbound
4610 * this check will fail and the matrix not applied again. This is OK because a simple
4611 * world matrix change reapplies the matrix - These checks here are only to satisfy the
4612 * needs of the vertex declaration.
4614 * World and view matrix go into the same gl matrix, so only apply them when neither is
4615 * dirty
4617 if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
4618 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
4619 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4620 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
4621 state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
4622 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
4623 state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
4625 if (context->last_was_vshader)
4627 updateFog = TRUE;
4629 if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
4630 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
4632 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4634 clipplane(context, state, STATE_CLIPPLANE(i));
4637 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
4638 state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
4640 else
4642 if(!context->last_was_vshader) {
4643 static BOOL warned = FALSE;
4644 if(!device->vs_clipping) {
4645 /* Disable all clip planes to get defined results on all drivers. See comment in the
4646 * state_clipping state handler
4648 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4650 gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i);
4651 checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
4654 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
4656 FIXME("Clipping not supported with vertex shaders\n");
4657 warned = TRUE;
4660 if (wasrhw)
4662 /* Apply the transform matrices when switching from rhw
4663 * drawing to vertex shaders. Vertex shaders themselves do
4664 * not need it, but the matrices are not reapplied
4665 * automatically when switching back from vertex shaders to
4666 * fixed function processing. So make sure we leave the fixed
4667 * function vertex processing states back in a sane state
4668 * before switching to shaders. */
4669 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4670 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4671 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
4672 transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
4674 updateFog = TRUE;
4676 /* Vertex shader clipping ignores the view matrix. Update all clipplanes
4677 * (Note: ARB shaders can read the clip planes for clipping emulation even if
4678 * device->vs_clipping is false.
4680 for (i = 0; i < gl_info->limits.clipplanes; ++i)
4682 clipplane(context, state, STATE_CLIPPLANE(i));
4687 /* Vertex and pixel shaders are applied together, so let the last dirty
4688 * state do the application. */
4689 if (!isStateDirty(context, STATE_PIXELSHADER))
4691 device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
4693 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)
4694 && (useVertexShaderFunction || usePixelShaderFunction))
4695 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4698 context->last_was_vshader = useVertexShaderFunction;
4700 if (updateFog)
4701 context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
4703 if (!useVertexShaderFunction)
4705 unsigned int i;
4707 for (i = 0; i < MAX_TEXTURES; ++i)
4709 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
4710 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
4714 if (transformed != wasrhw && !isStateDirty(context, STATE_RENDER(WINED3D_RS_ZENABLE)))
4715 state_zenable(context, state, STATE_RENDER(WINED3D_RS_ZENABLE));
4718 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4720 const struct wined3d_surface *target = state->fb->render_targets[0];
4721 const struct wined3d_gl_info *gl_info = context->gl_info;
4722 struct wined3d_viewport vp = state->viewport;
4724 if (vp.width > target->resource.width)
4725 vp.width = target->resource.width;
4726 if (vp.height > target->resource.height)
4727 vp.height = target->resource.height;
4729 gl_info->gl_ops.gl.p_glDepthRange(vp.min_z, vp.max_z);
4730 checkGLcall("glDepthRange");
4731 /* Note: GL requires lower left, DirectX supplies upper left. This is
4732 * reversed when using offscreen rendering. */
4733 if (context->render_offscreen)
4735 gl_info->gl_ops.gl.p_glViewport(vp.x, vp.y, vp.width, vp.height);
4737 else
4739 UINT width, height;
4741 target->get_drawable_size(context, &width, &height);
4742 gl_info->gl_ops.gl.p_glViewport(vp.x, (height - (vp.y + vp.height)),
4743 vp.width, vp.height);
4746 checkGLcall("glViewport");
4749 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4751 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
4752 transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
4753 if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
4754 state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
4755 /* Update the position fixup. */
4756 if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
4757 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
4760 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4762 const struct wined3d_gl_info *gl_info = context->gl_info;
4763 UINT Index = state_id - STATE_ACTIVELIGHT(0);
4764 const struct wined3d_light_info *lightInfo = state->lights[Index];
4766 if (!lightInfo)
4768 gl_info->gl_ops.gl.p_glDisable(GL_LIGHT0 + Index);
4769 checkGLcall("glDisable(GL_LIGHT0 + Index)");
4771 else
4773 float quad_att;
4774 float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
4776 /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
4777 gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
4778 gl_info->gl_ops.gl.p_glPushMatrix();
4779 gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
4781 /* Diffuse: */
4782 colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
4783 colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
4784 colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
4785 colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
4786 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
4787 checkGLcall("glLightfv");
4789 /* Specular */
4790 colRGBA[0] = lightInfo->OriginalParms.specular.r;
4791 colRGBA[1] = lightInfo->OriginalParms.specular.g;
4792 colRGBA[2] = lightInfo->OriginalParms.specular.b;
4793 colRGBA[3] = lightInfo->OriginalParms.specular.a;
4794 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
4795 checkGLcall("glLightfv");
4797 /* Ambient */
4798 colRGBA[0] = lightInfo->OriginalParms.ambient.r;
4799 colRGBA[1] = lightInfo->OriginalParms.ambient.g;
4800 colRGBA[2] = lightInfo->OriginalParms.ambient.b;
4801 colRGBA[3] = lightInfo->OriginalParms.ambient.a;
4802 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
4803 checkGLcall("glLightfv");
4805 if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
4806 quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
4807 else
4808 quad_att = 0.0f; /* 0 or MAX? (0 seems to be ok) */
4810 /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
4811 * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
4812 * Attenuation0 to NaN and crashes in the gl lib
4815 switch (lightInfo->OriginalParms.type)
4817 case WINED3D_LIGHT_POINT:
4818 /* Position */
4819 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4820 checkGLcall("glLightfv");
4821 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4822 checkGLcall("glLightf");
4823 /* Attenuation - Are these right? guessing... */
4824 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4825 lightInfo->OriginalParms.attenuation0);
4826 checkGLcall("glLightf");
4827 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4828 lightInfo->OriginalParms.attenuation1);
4829 checkGLcall("glLightf");
4830 if (quad_att < lightInfo->OriginalParms.attenuation2)
4831 quad_att = lightInfo->OriginalParms.attenuation2;
4832 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4833 checkGLcall("glLightf");
4834 /* FIXME: Range */
4835 break;
4837 case WINED3D_LIGHT_SPOT:
4838 /* Position */
4839 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4840 checkGLcall("glLightfv");
4841 /* Direction */
4842 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
4843 checkGLcall("glLightfv");
4844 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
4845 checkGLcall("glLightf");
4846 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4847 checkGLcall("glLightf");
4848 /* Attenuation - Are these right? guessing... */
4849 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION,
4850 lightInfo->OriginalParms.attenuation0);
4851 checkGLcall("glLightf");
4852 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION,
4853 lightInfo->OriginalParms.attenuation1);
4854 checkGLcall("glLightf");
4855 if (quad_att < lightInfo->OriginalParms.attenuation2)
4856 quad_att = lightInfo->OriginalParms.attenuation2;
4857 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
4858 checkGLcall("glLightf");
4859 /* FIXME: Range */
4860 break;
4862 case WINED3D_LIGHT_DIRECTIONAL:
4863 /* Direction */
4864 /* Note GL uses w position of 0 for direction! */
4865 gl_info->gl_ops.gl.p_glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
4866 checkGLcall("glLightfv");
4867 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
4868 checkGLcall("glLightf");
4869 gl_info->gl_ops.gl.p_glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
4870 checkGLcall("glLightf");
4871 break;
4873 default:
4874 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
4877 /* Restore the modelview matrix */
4878 gl_info->gl_ops.gl.p_glPopMatrix();
4880 gl_info->gl_ops.gl.p_glEnable(GL_LIGHT0 + Index);
4881 checkGLcall("glEnable(GL_LIGHT0 + Index)");
4885 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4887 const struct wined3d_gl_info *gl_info = context->gl_info;
4888 const RECT *r = &state->scissor_rect;
4890 /* Warning: glScissor uses window coordinates, not viewport coordinates,
4891 * so our viewport correction does not apply. Warning2: Even in windowed
4892 * mode the coords are relative to the window, not the screen. */
4893 TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
4895 if (context->render_offscreen)
4897 gl_info->gl_ops.gl.p_glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
4899 else
4901 const struct wined3d_surface *target = state->fb->render_targets[0];
4902 UINT height;
4903 UINT width;
4905 target->get_drawable_size(context, &width, &height);
4906 gl_info->gl_ops.gl.p_glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
4908 checkGLcall("glScissor");
4911 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4913 const struct wined3d_stream_info *stream_info = &context->swapchain->device->strided_streams;
4914 const struct wined3d_gl_info *gl_info = context->gl_info;
4916 if (state->user_stream || !state->index_buffer || !stream_info->all_vbo)
4918 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
4920 else
4922 struct wined3d_buffer *ib = state->index_buffer;
4923 GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
4927 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4929 const struct wined3d_gl_info *gl_info = context->gl_info;
4931 if (context->render_offscreen)
4933 gl_info->gl_ops.gl.p_glFrontFace(GL_CCW);
4934 checkGLcall("glFrontFace(GL_CCW)");
4936 else
4938 gl_info->gl_ops.gl.p_glFrontFace(GL_CW);
4939 checkGLcall("glFrontFace(GL_CW)");
4943 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4945 static BOOL warned;
4947 if (!warned)
4949 WARN("Point sprite coordinate origin switching not supported.\n");
4950 warned = TRUE;
4954 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
4956 const struct wined3d_gl_info *gl_info = context->gl_info;
4957 GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
4959 if (gl_info->supported[NV_POINT_SPRITE])
4961 GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
4962 checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
4966 const struct StateEntryTemplate misc_state_template[] = {
4967 { STATE_RENDER(WINED3D_RS_SRCBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4968 { STATE_RENDER(WINED3D_RS_DESTBLEND), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4969 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), state_blend }, WINED3D_GL_EXT_NONE },
4970 { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4971 { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4972 { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4973 { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4974 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4975 { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4976 { STATE_RENDER(WINED3D_RS_BLENDOPALPHA), { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE), NULL }, WINED3D_GL_EXT_NONE },
4977 { STATE_STREAMSRC, { STATE_STREAMSRC, streamsrc }, WINED3D_GL_EXT_NONE },
4978 { STATE_VDECL, { STATE_VDECL, vdecl_miscpart }, WINED3D_GL_EXT_NONE },
4979 { STATE_FRONTFACE, { STATE_FRONTFACE, frontface }, WINED3D_GL_EXT_NONE },
4980 { STATE_SCISSORRECT, { STATE_SCISSORRECT, scissorrect }, WINED3D_GL_EXT_NONE },
4981 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin }, WINED3D_GL_VERSION_2_0 },
4982 { STATE_POINTSPRITECOORDORIGIN, { STATE_POINTSPRITECOORDORIGIN, psorigin_w }, WINED3D_GL_EXT_NONE },
4984 /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
4985 * vshader loadings are untied from each other
4987 { STATE_VERTEXSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, shaderconstant }, WINED3D_GL_EXT_NONE },
4988 { STATE_PIXELSHADERCONSTANT, { STATE_VERTEXSHADERCONSTANT, NULL }, WINED3D_GL_EXT_NONE },
4989 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4990 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4991 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4992 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4993 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4994 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4995 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4996 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4997 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
4998 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
4999 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5000 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5001 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5002 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5003 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5004 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5005 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5006 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5007 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5008 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5009 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5010 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5011 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5012 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5013 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5014 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5015 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5016 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5017 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), shader_bumpenvmat }, WINED3D_GL_EXT_NONE },
5018 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5019 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5020 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00), NULL }, WINED3D_GL_EXT_NONE },
5021 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5022 { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5023 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5024 { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5025 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5026 { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5027 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5028 { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5029 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5030 { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5031 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5032 { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5033 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5034 { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5035 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), tex_bumpenvlscale }, WINED3D_GL_EXT_NONE },
5036 { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE), NULL }, WINED3D_GL_EXT_NONE },
5038 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_miscpart }, WINED3D_GL_EXT_NONE },
5039 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, indexbuffer }, ARB_VERTEX_BUFFER_OBJECT },
5040 { STATE_INDEXBUFFER, { STATE_INDEXBUFFER, state_nop }, WINED3D_GL_EXT_NONE },
5041 { STATE_RENDER(WINED3D_RS_ANTIALIAS), { STATE_RENDER(WINED3D_RS_ANTIALIAS), state_antialias }, WINED3D_GL_EXT_NONE },
5042 { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE), state_perspective }, WINED3D_GL_EXT_NONE },
5043 { STATE_RENDER(WINED3D_RS_ZENABLE), { STATE_RENDER(WINED3D_RS_ZENABLE), state_zenable }, WINED3D_GL_EXT_NONE },
5044 { STATE_RENDER(WINED3D_RS_WRAPU), { STATE_RENDER(WINED3D_RS_WRAPU), state_wrapu }, WINED3D_GL_EXT_NONE },
5045 { STATE_RENDER(WINED3D_RS_WRAPV), { STATE_RENDER(WINED3D_RS_WRAPV), state_wrapv }, WINED3D_GL_EXT_NONE },
5046 { STATE_RENDER(WINED3D_RS_FILLMODE), { STATE_RENDER(WINED3D_RS_FILLMODE), state_fillmode }, WINED3D_GL_EXT_NONE },
5047 { STATE_RENDER(WINED3D_RS_SHADEMODE), { STATE_RENDER(WINED3D_RS_SHADEMODE), state_shademode }, WINED3D_GL_EXT_NONE },
5048 { STATE_RENDER(WINED3D_RS_LINEPATTERN), { STATE_RENDER(WINED3D_RS_LINEPATTERN), state_linepattern }, WINED3D_GL_EXT_NONE },
5049 { STATE_RENDER(WINED3D_RS_MONOENABLE), { STATE_RENDER(WINED3D_RS_MONOENABLE), state_monoenable }, WINED3D_GL_EXT_NONE },
5050 { STATE_RENDER(WINED3D_RS_ROP2), { STATE_RENDER(WINED3D_RS_ROP2), state_rop2 }, WINED3D_GL_EXT_NONE },
5051 { STATE_RENDER(WINED3D_RS_PLANEMASK), { STATE_RENDER(WINED3D_RS_PLANEMASK), state_planemask }, WINED3D_GL_EXT_NONE },
5052 { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), { STATE_RENDER(WINED3D_RS_ZWRITEENABLE), state_zwritenable }, WINED3D_GL_EXT_NONE },
5053 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), state_alpha }, WINED3D_GL_EXT_NONE },
5054 { STATE_RENDER(WINED3D_RS_ALPHAREF), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5055 { STATE_RENDER(WINED3D_RS_ALPHAFUNC), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5056 { STATE_RENDER(WINED3D_RS_COLORKEYENABLE), { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE), NULL }, WINED3D_GL_EXT_NONE },
5057 { STATE_RENDER(WINED3D_RS_LASTPIXEL), { STATE_RENDER(WINED3D_RS_LASTPIXEL), state_lastpixel }, WINED3D_GL_EXT_NONE },
5058 { STATE_RENDER(WINED3D_RS_CULLMODE), { STATE_RENDER(WINED3D_RS_CULLMODE), state_cullmode }, WINED3D_GL_EXT_NONE },
5059 { STATE_RENDER(WINED3D_RS_ZFUNC), { STATE_RENDER(WINED3D_RS_ZFUNC), state_zfunc }, WINED3D_GL_EXT_NONE },
5060 { STATE_RENDER(WINED3D_RS_DITHERENABLE), { STATE_RENDER(WINED3D_RS_DITHERENABLE), state_ditherenable }, WINED3D_GL_EXT_NONE },
5061 { STATE_RENDER(WINED3D_RS_SUBPIXEL), { STATE_RENDER(WINED3D_RS_SUBPIXEL), state_subpixel }, WINED3D_GL_EXT_NONE },
5062 { STATE_RENDER(WINED3D_RS_SUBPIXELX), { STATE_RENDER(WINED3D_RS_SUBPIXELX), state_subpixelx }, WINED3D_GL_EXT_NONE },
5063 { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA), state_stippledalpha }, WINED3D_GL_EXT_NONE },
5064 { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), { STATE_RENDER(WINED3D_RS_STIPPLEENABLE), state_stippleenable }, WINED3D_GL_EXT_NONE },
5065 { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS), state_mipmaplodbias }, WINED3D_GL_EXT_NONE },
5066 { STATE_RENDER(WINED3D_RS_ANISOTROPY), { STATE_RENDER(WINED3D_RS_ANISOTROPY), state_anisotropy }, WINED3D_GL_EXT_NONE },
5067 { STATE_RENDER(WINED3D_RS_FLUSHBATCH), { STATE_RENDER(WINED3D_RS_FLUSHBATCH), state_flushbatch }, WINED3D_GL_EXT_NONE },
5068 { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE },
5069 { STATE_RENDER(WINED3D_RS_STENCILENABLE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), state_stencil }, WINED3D_GL_EXT_NONE },
5070 { STATE_RENDER(WINED3D_RS_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5071 { STATE_RENDER(WINED3D_RS_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5072 { STATE_RENDER(WINED3D_RS_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5073 { STATE_RENDER(WINED3D_RS_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5074 { STATE_RENDER(WINED3D_RS_STENCILREF), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5075 { STATE_RENDER(WINED3D_RS_STENCILMASK), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5076 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE },
5077 { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK), state_stencilwrite }, WINED3D_GL_EXT_NONE },
5078 { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5079 { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5080 { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5081 { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5082 { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC), { STATE_RENDER(WINED3D_RS_STENCILENABLE), NULL }, WINED3D_GL_EXT_NONE },
5083 { STATE_RENDER(WINED3D_RS_WRAP0), { STATE_RENDER(WINED3D_RS_WRAP0), state_wrap }, WINED3D_GL_EXT_NONE },
5084 { STATE_RENDER(WINED3D_RS_WRAP1), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5085 { STATE_RENDER(WINED3D_RS_WRAP2), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5086 { STATE_RENDER(WINED3D_RS_WRAP3), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5087 { STATE_RENDER(WINED3D_RS_WRAP4), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5088 { STATE_RENDER(WINED3D_RS_WRAP5), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5089 { STATE_RENDER(WINED3D_RS_WRAP6), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5090 { STATE_RENDER(WINED3D_RS_WRAP7), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5091 { STATE_RENDER(WINED3D_RS_WRAP8), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5092 { STATE_RENDER(WINED3D_RS_WRAP9), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5093 { STATE_RENDER(WINED3D_RS_WRAP10), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5094 { STATE_RENDER(WINED3D_RS_WRAP11), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5095 { STATE_RENDER(WINED3D_RS_WRAP12), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5096 { STATE_RENDER(WINED3D_RS_WRAP13), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5097 { STATE_RENDER(WINED3D_RS_WRAP14), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5098 { STATE_RENDER(WINED3D_RS_WRAP15), { STATE_RENDER(WINED3D_RS_WRAP0), NULL }, WINED3D_GL_EXT_NONE },
5099 { STATE_RENDER(WINED3D_RS_EXTENTS), { STATE_RENDER(WINED3D_RS_EXTENTS), state_extents }, WINED3D_GL_EXT_NONE },
5100 { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE), state_ckeyblend }, WINED3D_GL_EXT_NONE },
5101 { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING), state_swvp }, WINED3D_GL_EXT_NONE },
5102 { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE), state_patchedgestyle}, WINED3D_GL_EXT_NONE },
5103 { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS), state_patchsegments }, WINED3D_GL_EXT_NONE },
5104 { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), { STATE_RENDER(WINED3D_RS_POSITIONDEGREE), state_positiondegree}, WINED3D_GL_EXT_NONE },
5105 { STATE_RENDER(WINED3D_RS_NORMALDEGREE), { STATE_RENDER(WINED3D_RS_NORMALDEGREE), state_normaldegree }, WINED3D_GL_EXT_NONE },
5106 { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5107 { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5108 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5109 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5110 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5111 { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W), { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL }, WINED3D_GL_EXT_NONE },
5112 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb }, EXT_DEPTH_BOUNDS_TEST },
5113 { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation }, WINED3D_GL_EXT_NONE },
5114 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa }, ARB_MULTISAMPLE },
5115 { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS), state_msaa_w }, WINED3D_GL_EXT_NONE },
5116 { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK), state_multisampmask }, WINED3D_GL_EXT_NONE },
5117 { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN), state_debug_monitor }, WINED3D_GL_EXT_NONE },
5118 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite0 }, EXT_DRAW_BUFFERS2 },
5119 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), state_colorwrite }, WINED3D_GL_EXT_NONE },
5120 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop }, EXT_BLEND_MINMAX },
5121 { STATE_RENDER(WINED3D_RS_BLENDOP), { STATE_RENDER(WINED3D_RS_BLENDOP), state_blendop_w }, WINED3D_GL_EXT_NONE },
5122 { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE), state_scissor }, WINED3D_GL_EXT_NONE },
5123 { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), NULL }, WINED3D_GL_EXT_NONE },
5124 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), state_colorwrite1 }, EXT_DRAW_BUFFERS2 },
5125 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5126 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), state_colorwrite2 }, EXT_DRAW_BUFFERS2 },
5127 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5128 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), state_colorwrite3 }, EXT_DRAW_BUFFERS2 },
5129 { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3), { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5130 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor }, EXT_BLEND_COLOR },
5131 { STATE_RENDER(WINED3D_RS_BLENDFACTOR), { STATE_RENDER(WINED3D_RS_BLENDFACTOR), state_blendfactor_w }, WINED3D_GL_EXT_NONE },
5132 { STATE_RENDER(WINED3D_RS_DEPTHBIAS), { STATE_RENDER(WINED3D_RS_DEPTHBIAS), state_depthbias }, WINED3D_GL_EXT_NONE },
5133 { STATE_RENDER(WINED3D_RS_ZVISIBLE), { STATE_RENDER(WINED3D_RS_ZVISIBLE), state_zvisible }, WINED3D_GL_EXT_NONE },
5134 /* Samplers */
5135 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler }, WINED3D_GL_EXT_NONE },
5136 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler }, WINED3D_GL_EXT_NONE },
5137 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler }, WINED3D_GL_EXT_NONE },
5138 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler }, WINED3D_GL_EXT_NONE },
5139 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler }, WINED3D_GL_EXT_NONE },
5140 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler }, WINED3D_GL_EXT_NONE },
5141 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler }, WINED3D_GL_EXT_NONE },
5142 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler }, WINED3D_GL_EXT_NONE },
5143 { STATE_SAMPLER(8), { STATE_SAMPLER(8), sampler }, WINED3D_GL_EXT_NONE },
5144 { STATE_SAMPLER(9), { STATE_SAMPLER(9), sampler }, WINED3D_GL_EXT_NONE },
5145 { STATE_SAMPLER(10), { STATE_SAMPLER(10), sampler }, WINED3D_GL_EXT_NONE },
5146 { STATE_SAMPLER(11), { STATE_SAMPLER(11), sampler }, WINED3D_GL_EXT_NONE },
5147 { STATE_SAMPLER(12), { STATE_SAMPLER(12), sampler }, WINED3D_GL_EXT_NONE },
5148 { STATE_SAMPLER(13), { STATE_SAMPLER(13), sampler }, WINED3D_GL_EXT_NONE },
5149 { STATE_SAMPLER(14), { STATE_SAMPLER(14), sampler }, WINED3D_GL_EXT_NONE },
5150 { STATE_SAMPLER(15), { STATE_SAMPLER(15), sampler }, WINED3D_GL_EXT_NONE },
5151 { STATE_SAMPLER(16), /* Vertex sampler 0 */ { STATE_SAMPLER(16), sampler }, WINED3D_GL_EXT_NONE },
5152 { STATE_SAMPLER(17), /* Vertex sampler 1 */ { STATE_SAMPLER(17), sampler }, WINED3D_GL_EXT_NONE },
5153 { STATE_SAMPLER(18), /* Vertex sampler 2 */ { STATE_SAMPLER(18), sampler }, WINED3D_GL_EXT_NONE },
5154 { STATE_SAMPLER(19), /* Vertex sampler 3 */ { STATE_SAMPLER(19), sampler }, WINED3D_GL_EXT_NONE },
5155 { STATE_BASEVERTEXINDEX, { STATE_BASEVERTEXINDEX, state_nop, }, ARB_DRAW_ELEMENTS_BASE_VERTEX },
5156 { STATE_BASEVERTEXINDEX, { STATE_STREAMSRC, NULL, }, WINED3D_GL_EXT_NONE },
5157 { STATE_FRAMEBUFFER, { STATE_FRAMEBUFFER, context_state_fb }, WINED3D_GL_EXT_NONE },
5158 { STATE_PIXELSHADER, { STATE_PIXELSHADER, context_state_drawbuf},WINED3D_GL_EXT_NONE },
5159 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5162 const struct StateEntryTemplate ffp_vertexstate_template[] = {
5163 { STATE_VDECL, { STATE_VDECL, vertexdeclaration }, WINED3D_GL_EXT_NONE },
5164 { STATE_VSHADER, { STATE_VDECL, NULL }, WINED3D_GL_EXT_NONE },
5165 { STATE_MATERIAL, { STATE_RENDER(WINED3D_RS_SPECULARENABLE), NULL }, WINED3D_GL_EXT_NONE },
5166 { STATE_RENDER(WINED3D_RS_SPECULARENABLE), { STATE_RENDER(WINED3D_RS_SPECULARENABLE), state_specularenable}, WINED3D_GL_EXT_NONE },
5167 /* Clip planes */
5168 { STATE_CLIPPLANE(0), { STATE_CLIPPLANE(0), clipplane }, WINED3D_GL_EXT_NONE },
5169 { STATE_CLIPPLANE(1), { STATE_CLIPPLANE(1), clipplane }, WINED3D_GL_EXT_NONE },
5170 { STATE_CLIPPLANE(2), { STATE_CLIPPLANE(2), clipplane }, WINED3D_GL_EXT_NONE },
5171 { STATE_CLIPPLANE(3), { STATE_CLIPPLANE(3), clipplane }, WINED3D_GL_EXT_NONE },
5172 { STATE_CLIPPLANE(4), { STATE_CLIPPLANE(4), clipplane }, WINED3D_GL_EXT_NONE },
5173 { STATE_CLIPPLANE(5), { STATE_CLIPPLANE(5), clipplane }, WINED3D_GL_EXT_NONE },
5174 { STATE_CLIPPLANE(6), { STATE_CLIPPLANE(6), clipplane }, WINED3D_GL_EXT_NONE },
5175 { STATE_CLIPPLANE(7), { STATE_CLIPPLANE(7), clipplane }, WINED3D_GL_EXT_NONE },
5176 { STATE_CLIPPLANE(8), { STATE_CLIPPLANE(8), clipplane }, WINED3D_GL_EXT_NONE },
5177 { STATE_CLIPPLANE(9), { STATE_CLIPPLANE(9), clipplane }, WINED3D_GL_EXT_NONE },
5178 { STATE_CLIPPLANE(10), { STATE_CLIPPLANE(10), clipplane }, WINED3D_GL_EXT_NONE },
5179 { STATE_CLIPPLANE(11), { STATE_CLIPPLANE(11), clipplane }, WINED3D_GL_EXT_NONE },
5180 { STATE_CLIPPLANE(12), { STATE_CLIPPLANE(12), clipplane }, WINED3D_GL_EXT_NONE },
5181 { STATE_CLIPPLANE(13), { STATE_CLIPPLANE(13), clipplane }, WINED3D_GL_EXT_NONE },
5182 { STATE_CLIPPLANE(14), { STATE_CLIPPLANE(14), clipplane }, WINED3D_GL_EXT_NONE },
5183 { STATE_CLIPPLANE(15), { STATE_CLIPPLANE(15), clipplane }, WINED3D_GL_EXT_NONE },
5184 { STATE_CLIPPLANE(16), { STATE_CLIPPLANE(16), clipplane }, WINED3D_GL_EXT_NONE },
5185 { STATE_CLIPPLANE(17), { STATE_CLIPPLANE(17), clipplane }, WINED3D_GL_EXT_NONE },
5186 { STATE_CLIPPLANE(18), { STATE_CLIPPLANE(18), clipplane }, WINED3D_GL_EXT_NONE },
5187 { STATE_CLIPPLANE(19), { STATE_CLIPPLANE(19), clipplane }, WINED3D_GL_EXT_NONE },
5188 { STATE_CLIPPLANE(20), { STATE_CLIPPLANE(20), clipplane }, WINED3D_GL_EXT_NONE },
5189 { STATE_CLIPPLANE(21), { STATE_CLIPPLANE(21), clipplane }, WINED3D_GL_EXT_NONE },
5190 { STATE_CLIPPLANE(22), { STATE_CLIPPLANE(22), clipplane }, WINED3D_GL_EXT_NONE },
5191 { STATE_CLIPPLANE(23), { STATE_CLIPPLANE(23), clipplane }, WINED3D_GL_EXT_NONE },
5192 { STATE_CLIPPLANE(24), { STATE_CLIPPLANE(24), clipplane }, WINED3D_GL_EXT_NONE },
5193 { STATE_CLIPPLANE(25), { STATE_CLIPPLANE(25), clipplane }, WINED3D_GL_EXT_NONE },
5194 { STATE_CLIPPLANE(26), { STATE_CLIPPLANE(26), clipplane }, WINED3D_GL_EXT_NONE },
5195 { STATE_CLIPPLANE(27), { STATE_CLIPPLANE(27), clipplane }, WINED3D_GL_EXT_NONE },
5196 { STATE_CLIPPLANE(28), { STATE_CLIPPLANE(28), clipplane }, WINED3D_GL_EXT_NONE },
5197 { STATE_CLIPPLANE(29), { STATE_CLIPPLANE(29), clipplane }, WINED3D_GL_EXT_NONE },
5198 { STATE_CLIPPLANE(30), { STATE_CLIPPLANE(30), clipplane }, WINED3D_GL_EXT_NONE },
5199 { STATE_CLIPPLANE(31), { STATE_CLIPPLANE(31), clipplane }, WINED3D_GL_EXT_NONE },
5200 /* Lights */
5201 { STATE_ACTIVELIGHT(0), { STATE_ACTIVELIGHT(0), light }, WINED3D_GL_EXT_NONE },
5202 { STATE_ACTIVELIGHT(1), { STATE_ACTIVELIGHT(1), light }, WINED3D_GL_EXT_NONE },
5203 { STATE_ACTIVELIGHT(2), { STATE_ACTIVELIGHT(2), light }, WINED3D_GL_EXT_NONE },
5204 { STATE_ACTIVELIGHT(3), { STATE_ACTIVELIGHT(3), light }, WINED3D_GL_EXT_NONE },
5205 { STATE_ACTIVELIGHT(4), { STATE_ACTIVELIGHT(4), light }, WINED3D_GL_EXT_NONE },
5206 { STATE_ACTIVELIGHT(5), { STATE_ACTIVELIGHT(5), light }, WINED3D_GL_EXT_NONE },
5207 { STATE_ACTIVELIGHT(6), { STATE_ACTIVELIGHT(6), light }, WINED3D_GL_EXT_NONE },
5208 { STATE_ACTIVELIGHT(7), { STATE_ACTIVELIGHT(7), light }, WINED3D_GL_EXT_NONE },
5209 /* Viewport */
5210 { STATE_VIEWPORT, { STATE_VIEWPORT, viewport_vertexpart }, WINED3D_GL_EXT_NONE },
5211 /* Transform states follow */
5212 { STATE_TRANSFORM(WINED3D_TS_VIEW), { STATE_TRANSFORM(WINED3D_TS_VIEW), transform_view }, WINED3D_GL_EXT_NONE },
5213 { STATE_TRANSFORM(WINED3D_TS_PROJECTION), { STATE_TRANSFORM(WINED3D_TS_PROJECTION), transform_projection}, WINED3D_GL_EXT_NONE },
5214 { STATE_TRANSFORM(WINED3D_TS_TEXTURE0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5215 { STATE_TRANSFORM(WINED3D_TS_TEXTURE1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5216 { STATE_TRANSFORM(WINED3D_TS_TEXTURE2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5217 { STATE_TRANSFORM(WINED3D_TS_TEXTURE3), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5218 { STATE_TRANSFORM(WINED3D_TS_TEXTURE4), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5219 { STATE_TRANSFORM(WINED3D_TS_TEXTURE5), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5220 { STATE_TRANSFORM(WINED3D_TS_TEXTURE6), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5221 { STATE_TRANSFORM(WINED3D_TS_TEXTURE7), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE },
5222 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 0)), transform_world }, WINED3D_GL_EXT_NONE },
5223 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 1)), transform_worldex }, WINED3D_GL_EXT_NONE },
5224 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 2)), transform_worldex }, WINED3D_GL_EXT_NONE },
5225 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 3)), transform_worldex }, WINED3D_GL_EXT_NONE },
5226 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 4)), transform_worldex }, WINED3D_GL_EXT_NONE },
5227 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 5)), transform_worldex }, WINED3D_GL_EXT_NONE },
5228 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 6)), transform_worldex }, WINED3D_GL_EXT_NONE },
5229 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 7)), transform_worldex }, WINED3D_GL_EXT_NONE },
5230 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 8)), transform_worldex }, WINED3D_GL_EXT_NONE },
5231 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 9)), transform_worldex }, WINED3D_GL_EXT_NONE },
5232 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)), transform_worldex }, WINED3D_GL_EXT_NONE },
5233 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)), transform_worldex }, WINED3D_GL_EXT_NONE },
5234 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)), transform_worldex }, WINED3D_GL_EXT_NONE },
5235 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)), transform_worldex }, WINED3D_GL_EXT_NONE },
5236 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)), transform_worldex }, WINED3D_GL_EXT_NONE },
5237 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)), transform_worldex }, WINED3D_GL_EXT_NONE },
5238 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)), transform_worldex }, WINED3D_GL_EXT_NONE },
5239 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)), transform_worldex }, WINED3D_GL_EXT_NONE },
5240 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)), transform_worldex }, WINED3D_GL_EXT_NONE },
5241 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)), transform_worldex }, WINED3D_GL_EXT_NONE },
5242 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)), transform_worldex }, WINED3D_GL_EXT_NONE },
5243 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)), transform_worldex }, WINED3D_GL_EXT_NONE },
5244 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)), transform_worldex }, WINED3D_GL_EXT_NONE },
5245 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)), transform_worldex }, WINED3D_GL_EXT_NONE },
5246 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)), transform_worldex }, WINED3D_GL_EXT_NONE },
5247 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)), transform_worldex }, WINED3D_GL_EXT_NONE },
5248 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)), transform_worldex }, WINED3D_GL_EXT_NONE },
5249 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)), transform_worldex }, WINED3D_GL_EXT_NONE },
5250 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)), transform_worldex }, WINED3D_GL_EXT_NONE },
5251 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)), transform_worldex }, WINED3D_GL_EXT_NONE },
5252 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)), transform_worldex }, WINED3D_GL_EXT_NONE },
5253 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)), transform_worldex }, WINED3D_GL_EXT_NONE },
5254 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)), transform_worldex }, WINED3D_GL_EXT_NONE },
5255 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)), transform_worldex }, WINED3D_GL_EXT_NONE },
5256 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)), transform_worldex }, WINED3D_GL_EXT_NONE },
5257 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)), transform_worldex }, WINED3D_GL_EXT_NONE },
5258 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)), transform_worldex }, WINED3D_GL_EXT_NONE },
5259 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)), transform_worldex }, WINED3D_GL_EXT_NONE },
5260 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)), transform_worldex }, WINED3D_GL_EXT_NONE },
5261 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)), transform_worldex }, WINED3D_GL_EXT_NONE },
5262 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)), transform_worldex }, WINED3D_GL_EXT_NONE },
5263 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)), transform_worldex }, WINED3D_GL_EXT_NONE },
5264 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)), transform_worldex }, WINED3D_GL_EXT_NONE },
5265 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)), transform_worldex }, WINED3D_GL_EXT_NONE },
5266 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)), transform_worldex }, WINED3D_GL_EXT_NONE },
5267 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)), transform_worldex }, WINED3D_GL_EXT_NONE },
5268 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)), transform_worldex }, WINED3D_GL_EXT_NONE },
5269 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)), transform_worldex }, WINED3D_GL_EXT_NONE },
5270 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)), transform_worldex }, WINED3D_GL_EXT_NONE },
5271 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)), transform_worldex }, WINED3D_GL_EXT_NONE },
5272 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)), transform_worldex }, WINED3D_GL_EXT_NONE },
5273 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)), transform_worldex }, WINED3D_GL_EXT_NONE },
5274 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)), transform_worldex }, WINED3D_GL_EXT_NONE },
5275 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)), transform_worldex }, WINED3D_GL_EXT_NONE },
5276 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)), transform_worldex }, WINED3D_GL_EXT_NONE },
5277 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)), transform_worldex }, WINED3D_GL_EXT_NONE },
5278 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)), transform_worldex }, WINED3D_GL_EXT_NONE },
5279 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)), transform_worldex }, WINED3D_GL_EXT_NONE },
5280 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)), transform_worldex }, WINED3D_GL_EXT_NONE },
5281 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)), transform_worldex }, WINED3D_GL_EXT_NONE },
5282 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)), transform_worldex }, WINED3D_GL_EXT_NONE },
5283 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)), transform_worldex }, WINED3D_GL_EXT_NONE },
5284 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)), transform_worldex }, WINED3D_GL_EXT_NONE },
5285 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)), transform_worldex }, WINED3D_GL_EXT_NONE },
5286 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)), transform_worldex }, WINED3D_GL_EXT_NONE },
5287 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)), transform_worldex }, WINED3D_GL_EXT_NONE },
5288 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)), transform_worldex }, WINED3D_GL_EXT_NONE },
5289 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)), transform_worldex }, WINED3D_GL_EXT_NONE },
5290 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)), transform_worldex }, WINED3D_GL_EXT_NONE },
5291 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)), transform_worldex }, WINED3D_GL_EXT_NONE },
5292 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)), transform_worldex }, WINED3D_GL_EXT_NONE },
5293 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)), transform_worldex }, WINED3D_GL_EXT_NONE },
5294 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)), transform_worldex }, WINED3D_GL_EXT_NONE },
5295 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)), transform_worldex }, WINED3D_GL_EXT_NONE },
5296 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)), transform_worldex }, WINED3D_GL_EXT_NONE },
5297 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)), transform_worldex }, WINED3D_GL_EXT_NONE },
5298 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)), transform_worldex }, WINED3D_GL_EXT_NONE },
5299 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)), transform_worldex }, WINED3D_GL_EXT_NONE },
5300 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)), transform_worldex }, WINED3D_GL_EXT_NONE },
5301 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)), transform_worldex }, WINED3D_GL_EXT_NONE },
5302 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)), transform_worldex }, WINED3D_GL_EXT_NONE },
5303 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)), transform_worldex }, WINED3D_GL_EXT_NONE },
5304 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)), transform_worldex }, WINED3D_GL_EXT_NONE },
5305 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)), transform_worldex }, WINED3D_GL_EXT_NONE },
5306 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)), transform_worldex }, WINED3D_GL_EXT_NONE },
5307 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)), transform_worldex }, WINED3D_GL_EXT_NONE },
5308 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)), transform_worldex }, WINED3D_GL_EXT_NONE },
5309 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)), transform_worldex }, WINED3D_GL_EXT_NONE },
5310 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)), transform_worldex }, WINED3D_GL_EXT_NONE },
5311 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)), transform_worldex }, WINED3D_GL_EXT_NONE },
5312 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)), transform_worldex }, WINED3D_GL_EXT_NONE },
5313 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)), transform_worldex }, WINED3D_GL_EXT_NONE },
5314 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)), transform_worldex }, WINED3D_GL_EXT_NONE },
5315 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)), transform_worldex }, WINED3D_GL_EXT_NONE },
5316 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)), transform_worldex }, WINED3D_GL_EXT_NONE },
5317 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)), transform_worldex }, WINED3D_GL_EXT_NONE },
5318 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)), transform_worldex }, WINED3D_GL_EXT_NONE },
5319 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)), transform_worldex }, WINED3D_GL_EXT_NONE },
5320 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)), transform_worldex }, WINED3D_GL_EXT_NONE },
5321 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)), transform_worldex }, WINED3D_GL_EXT_NONE },
5322 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)), transform_worldex }, WINED3D_GL_EXT_NONE },
5323 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)), transform_worldex }, WINED3D_GL_EXT_NONE },
5324 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)), transform_worldex }, WINED3D_GL_EXT_NONE },
5325 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)), transform_worldex }, WINED3D_GL_EXT_NONE },
5326 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)), transform_worldex }, WINED3D_GL_EXT_NONE },
5327 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)), transform_worldex }, WINED3D_GL_EXT_NONE },
5328 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)), transform_worldex }, WINED3D_GL_EXT_NONE },
5329 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)), transform_worldex }, WINED3D_GL_EXT_NONE },
5330 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)), transform_worldex }, WINED3D_GL_EXT_NONE },
5331 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)), transform_worldex }, WINED3D_GL_EXT_NONE },
5332 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)), transform_worldex }, WINED3D_GL_EXT_NONE },
5333 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)), transform_worldex }, WINED3D_GL_EXT_NONE },
5334 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)), transform_worldex }, WINED3D_GL_EXT_NONE },
5335 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)), transform_worldex }, WINED3D_GL_EXT_NONE },
5336 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)), transform_worldex }, WINED3D_GL_EXT_NONE },
5337 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)), transform_worldex }, WINED3D_GL_EXT_NONE },
5338 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)), transform_worldex }, WINED3D_GL_EXT_NONE },
5339 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)), transform_worldex }, WINED3D_GL_EXT_NONE },
5340 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)), transform_worldex }, WINED3D_GL_EXT_NONE },
5341 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)), transform_worldex }, WINED3D_GL_EXT_NONE },
5342 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)), transform_worldex }, WINED3D_GL_EXT_NONE },
5343 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)), transform_worldex }, WINED3D_GL_EXT_NONE },
5344 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)), transform_worldex }, WINED3D_GL_EXT_NONE },
5345 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)), transform_worldex }, WINED3D_GL_EXT_NONE },
5346 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)), transform_worldex }, WINED3D_GL_EXT_NONE },
5347 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)), transform_worldex }, WINED3D_GL_EXT_NONE },
5348 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)), transform_worldex }, WINED3D_GL_EXT_NONE },
5349 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)), transform_worldex }, WINED3D_GL_EXT_NONE },
5350 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)), transform_worldex }, WINED3D_GL_EXT_NONE },
5351 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)), transform_worldex }, WINED3D_GL_EXT_NONE },
5352 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)), transform_worldex }, WINED3D_GL_EXT_NONE },
5353 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)), transform_worldex }, WINED3D_GL_EXT_NONE },
5354 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)), transform_worldex }, WINED3D_GL_EXT_NONE },
5355 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)), transform_worldex }, WINED3D_GL_EXT_NONE },
5356 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)), transform_worldex }, WINED3D_GL_EXT_NONE },
5357 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)), transform_worldex }, WINED3D_GL_EXT_NONE },
5358 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)), transform_worldex }, WINED3D_GL_EXT_NONE },
5359 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)), transform_worldex }, WINED3D_GL_EXT_NONE },
5360 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)), transform_worldex }, WINED3D_GL_EXT_NONE },
5361 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)), transform_worldex }, WINED3D_GL_EXT_NONE },
5362 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)), transform_worldex }, WINED3D_GL_EXT_NONE },
5363 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)), transform_worldex }, WINED3D_GL_EXT_NONE },
5364 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)), transform_worldex }, WINED3D_GL_EXT_NONE },
5365 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)), transform_worldex }, WINED3D_GL_EXT_NONE },
5366 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)), transform_worldex }, WINED3D_GL_EXT_NONE },
5367 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)), transform_worldex }, WINED3D_GL_EXT_NONE },
5368 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)), transform_worldex }, WINED3D_GL_EXT_NONE },
5369 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)), transform_worldex }, WINED3D_GL_EXT_NONE },
5370 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)), transform_worldex }, WINED3D_GL_EXT_NONE },
5371 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)), transform_worldex }, WINED3D_GL_EXT_NONE },
5372 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)), transform_worldex }, WINED3D_GL_EXT_NONE },
5373 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)), transform_worldex }, WINED3D_GL_EXT_NONE },
5374 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)), transform_worldex }, WINED3D_GL_EXT_NONE },
5375 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)), transform_worldex }, WINED3D_GL_EXT_NONE },
5376 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)), transform_worldex }, WINED3D_GL_EXT_NONE },
5377 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)), transform_worldex }, WINED3D_GL_EXT_NONE },
5378 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)), transform_worldex }, WINED3D_GL_EXT_NONE },
5379 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)), transform_worldex }, WINED3D_GL_EXT_NONE },
5380 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)), transform_worldex }, WINED3D_GL_EXT_NONE },
5381 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)), transform_worldex }, WINED3D_GL_EXT_NONE },
5382 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)), transform_worldex }, WINED3D_GL_EXT_NONE },
5383 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)), transform_worldex }, WINED3D_GL_EXT_NONE },
5384 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)), transform_worldex }, WINED3D_GL_EXT_NONE },
5385 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)), transform_worldex }, WINED3D_GL_EXT_NONE },
5386 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)), transform_worldex }, WINED3D_GL_EXT_NONE },
5387 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)), transform_worldex }, WINED3D_GL_EXT_NONE },
5388 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)), transform_worldex }, WINED3D_GL_EXT_NONE },
5389 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)), transform_worldex }, WINED3D_GL_EXT_NONE },
5390 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)), transform_worldex }, WINED3D_GL_EXT_NONE },
5391 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)), transform_worldex }, WINED3D_GL_EXT_NONE },
5392 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)), transform_worldex }, WINED3D_GL_EXT_NONE },
5393 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)), transform_worldex }, WINED3D_GL_EXT_NONE },
5394 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)), transform_worldex }, WINED3D_GL_EXT_NONE },
5395 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)), transform_worldex }, WINED3D_GL_EXT_NONE },
5396 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)), transform_worldex }, WINED3D_GL_EXT_NONE },
5397 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)), transform_worldex }, WINED3D_GL_EXT_NONE },
5398 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)), transform_worldex }, WINED3D_GL_EXT_NONE },
5399 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)), transform_worldex }, WINED3D_GL_EXT_NONE },
5400 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)), transform_worldex }, WINED3D_GL_EXT_NONE },
5401 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)), transform_worldex }, WINED3D_GL_EXT_NONE },
5402 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)), transform_worldex }, WINED3D_GL_EXT_NONE },
5403 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)), transform_worldex }, WINED3D_GL_EXT_NONE },
5404 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)), transform_worldex }, WINED3D_GL_EXT_NONE },
5405 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)), transform_worldex }, WINED3D_GL_EXT_NONE },
5406 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)), transform_worldex }, WINED3D_GL_EXT_NONE },
5407 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)), transform_worldex }, WINED3D_GL_EXT_NONE },
5408 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)), transform_worldex }, WINED3D_GL_EXT_NONE },
5409 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)), transform_worldex }, WINED3D_GL_EXT_NONE },
5410 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)), transform_worldex }, WINED3D_GL_EXT_NONE },
5411 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)), transform_worldex }, WINED3D_GL_EXT_NONE },
5412 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)), transform_worldex }, WINED3D_GL_EXT_NONE },
5413 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)), transform_worldex }, WINED3D_GL_EXT_NONE },
5414 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)), transform_worldex }, WINED3D_GL_EXT_NONE },
5415 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)), transform_worldex }, WINED3D_GL_EXT_NONE },
5416 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)), transform_worldex }, WINED3D_GL_EXT_NONE },
5417 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)), transform_worldex }, WINED3D_GL_EXT_NONE },
5418 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)), transform_worldex }, WINED3D_GL_EXT_NONE },
5419 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)), transform_worldex }, WINED3D_GL_EXT_NONE },
5420 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)), transform_worldex }, WINED3D_GL_EXT_NONE },
5421 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)), transform_worldex }, WINED3D_GL_EXT_NONE },
5422 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)), transform_worldex }, WINED3D_GL_EXT_NONE },
5423 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)), transform_worldex }, WINED3D_GL_EXT_NONE },
5424 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)), transform_worldex }, WINED3D_GL_EXT_NONE },
5425 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)), transform_worldex }, WINED3D_GL_EXT_NONE },
5426 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)), transform_worldex }, WINED3D_GL_EXT_NONE },
5427 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)), transform_worldex }, WINED3D_GL_EXT_NONE },
5428 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)), transform_worldex }, WINED3D_GL_EXT_NONE },
5429 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)), transform_worldex }, WINED3D_GL_EXT_NONE },
5430 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)), transform_worldex }, WINED3D_GL_EXT_NONE },
5431 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)), transform_worldex }, WINED3D_GL_EXT_NONE },
5432 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)), transform_worldex }, WINED3D_GL_EXT_NONE },
5433 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)), transform_worldex }, WINED3D_GL_EXT_NONE },
5434 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)), transform_worldex }, WINED3D_GL_EXT_NONE },
5435 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)), transform_worldex }, WINED3D_GL_EXT_NONE },
5436 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)), transform_worldex }, WINED3D_GL_EXT_NONE },
5437 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)), transform_worldex }, WINED3D_GL_EXT_NONE },
5438 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)), transform_worldex }, WINED3D_GL_EXT_NONE },
5439 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)), transform_worldex }, WINED3D_GL_EXT_NONE },
5440 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)), transform_worldex }, WINED3D_GL_EXT_NONE },
5441 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)), transform_worldex }, WINED3D_GL_EXT_NONE },
5442 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)), transform_worldex }, WINED3D_GL_EXT_NONE },
5443 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)), transform_worldex }, WINED3D_GL_EXT_NONE },
5444 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)), transform_worldex }, WINED3D_GL_EXT_NONE },
5445 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)), transform_worldex }, WINED3D_GL_EXT_NONE },
5446 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)), transform_worldex }, WINED3D_GL_EXT_NONE },
5447 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)), transform_worldex }, WINED3D_GL_EXT_NONE },
5448 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)), transform_worldex }, WINED3D_GL_EXT_NONE },
5449 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)), transform_worldex }, WINED3D_GL_EXT_NONE },
5450 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)), transform_worldex }, WINED3D_GL_EXT_NONE },
5451 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)), transform_worldex }, WINED3D_GL_EXT_NONE },
5452 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)), transform_worldex }, WINED3D_GL_EXT_NONE },
5453 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)), transform_worldex }, WINED3D_GL_EXT_NONE },
5454 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)), transform_worldex }, WINED3D_GL_EXT_NONE },
5455 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)), transform_worldex }, WINED3D_GL_EXT_NONE },
5456 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)), transform_worldex }, WINED3D_GL_EXT_NONE },
5457 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)), transform_worldex }, WINED3D_GL_EXT_NONE },
5458 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)), transform_worldex }, WINED3D_GL_EXT_NONE },
5459 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)), transform_worldex }, WINED3D_GL_EXT_NONE },
5460 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)), transform_worldex }, WINED3D_GL_EXT_NONE },
5461 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)), transform_worldex }, WINED3D_GL_EXT_NONE },
5462 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)), transform_worldex }, WINED3D_GL_EXT_NONE },
5463 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)), transform_worldex }, WINED3D_GL_EXT_NONE },
5464 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)), transform_worldex }, WINED3D_GL_EXT_NONE },
5465 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)), transform_worldex }, WINED3D_GL_EXT_NONE },
5466 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)), transform_worldex }, WINED3D_GL_EXT_NONE },
5467 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)), transform_worldex }, WINED3D_GL_EXT_NONE },
5468 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)), transform_worldex }, WINED3D_GL_EXT_NONE },
5469 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)), transform_worldex }, WINED3D_GL_EXT_NONE },
5470 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)), transform_worldex }, WINED3D_GL_EXT_NONE },
5471 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)), transform_worldex }, WINED3D_GL_EXT_NONE },
5472 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)), transform_worldex }, WINED3D_GL_EXT_NONE },
5473 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)), transform_worldex }, WINED3D_GL_EXT_NONE },
5474 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)), transform_worldex }, WINED3D_GL_EXT_NONE },
5475 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)), transform_worldex }, WINED3D_GL_EXT_NONE },
5476 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)), transform_worldex }, WINED3D_GL_EXT_NONE },
5477 { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)), transform_worldex }, WINED3D_GL_EXT_NONE },
5478 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5479 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5480 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5481 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5482 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5483 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5484 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5485 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE },
5486 { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5487 { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5488 { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5489 { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5490 { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5491 { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5492 { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5493 { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX), tex_coordindex }, WINED3D_GL_EXT_NONE },
5494 /* Fog */
5495 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_vertexpart}, WINED3D_GL_EXT_NONE },
5496 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5497 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5498 { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5499 { STATE_RENDER(WINED3D_RS_CLIPPING), { STATE_RENDER(WINED3D_RS_CLIPPING), state_clipping }, WINED3D_GL_EXT_NONE },
5500 { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE), { STATE_RENDER(WINED3D_RS_CLIPPING), NULL }, WINED3D_GL_EXT_NONE },
5501 { STATE_RENDER(WINED3D_RS_LIGHTING), { STATE_RENDER(WINED3D_RS_LIGHTING), state_lighting }, WINED3D_GL_EXT_NONE },
5502 { STATE_RENDER(WINED3D_RS_AMBIENT), { STATE_RENDER(WINED3D_RS_AMBIENT), state_ambient }, WINED3D_GL_EXT_NONE },
5503 { STATE_RENDER(WINED3D_RS_COLORVERTEX), { STATE_RENDER(WINED3D_RS_COLORVERTEX), state_colormat }, WINED3D_GL_EXT_NONE },
5504 { STATE_RENDER(WINED3D_RS_LOCALVIEWER), { STATE_RENDER(WINED3D_RS_LOCALVIEWER), state_localviewer }, WINED3D_GL_EXT_NONE },
5505 { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS), state_normalize }, WINED3D_GL_EXT_NONE },
5506 { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5507 { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5508 { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5509 { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE), { STATE_RENDER(WINED3D_RS_COLORVERTEX), NULL }, WINED3D_GL_EXT_NONE },
5510 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend }, ARB_VERTEX_BLEND },
5511 { STATE_RENDER(WINED3D_RS_VERTEXBLEND), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), state_vertexblend_w }, WINED3D_GL_EXT_NONE },
5512 { STATE_RENDER(WINED3D_RS_POINTSIZE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5513 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_arb }, ARB_POINT_PARAMETERS },
5514 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_ext }, EXT_POINT_PARAMETERS },
5515 { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), state_psizemin_w }, WINED3D_GL_EXT_NONE },
5516 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite }, ARB_POINT_SPRITE },
5517 { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE), state_pointsprite_w }, WINED3D_GL_EXT_NONE },
5518 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), state_pscale }, WINED3D_GL_EXT_NONE },
5519 { STATE_RENDER(WINED3D_RS_POINTSCALE_A), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5520 { STATE_RENDER(WINED3D_RS_POINTSCALE_B), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5521 { STATE_RENDER(WINED3D_RS_POINTSCALE_C), { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE), NULL }, WINED3D_GL_EXT_NONE },
5522 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, ARB_POINT_PARAMETERS },
5523 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, EXT_POINT_PARAMETERS },
5524 { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE },
5525 { STATE_RENDER(WINED3D_RS_TWEENFACTOR), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5526 { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), { STATE_RENDER(WINED3D_RS_VERTEXBLEND), NULL }, WINED3D_GL_EXT_NONE },
5528 /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
5529 * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
5530 * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
5532 { STATE_SAMPLER(0), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5533 { STATE_SAMPLER(0), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5534 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5535 { STATE_SAMPLER(1), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5536 { STATE_SAMPLER(1), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5537 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5538 { STATE_SAMPLER(2), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5539 { STATE_SAMPLER(2), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5540 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5541 { STATE_SAMPLER(3), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5542 { STATE_SAMPLER(3), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5543 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5544 { STATE_SAMPLER(4), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5545 { STATE_SAMPLER(4), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5546 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5547 { STATE_SAMPLER(5), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5548 { STATE_SAMPLER(5), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5549 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5550 { STATE_SAMPLER(6), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5551 { STATE_SAMPLER(6), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5552 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5553 { STATE_SAMPLER(7), { 0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO },
5554 { STATE_SAMPLER(7), { 0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT },
5555 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE },
5556 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5559 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
5560 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5561 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5562 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5563 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5564 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5565 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5566 { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5567 { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5568 { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5569 { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5570 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5571 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5572 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5573 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5574 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5575 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5576 { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5577 { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5578 { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5579 { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5580 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5581 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5582 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5583 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5584 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5585 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5586 { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5587 { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5588 { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5589 { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5590 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5591 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5592 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5593 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5594 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5595 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5596 { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5597 { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5598 { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5599 { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5600 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5601 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5602 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5603 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5604 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5605 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5606 { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5607 { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5608 { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5609 { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5610 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5611 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5612 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5613 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5614 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5615 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5616 { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5617 { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5618 { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5619 { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5620 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5621 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5622 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5623 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5624 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5625 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5626 { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5627 { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5628 { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5629 { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5630 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), tex_colorop }, WINED3D_GL_EXT_NONE },
5631 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5632 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5633 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), tex_alphaop }, WINED3D_GL_EXT_NONE },
5634 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5635 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5636 { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5637 { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0), { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP), NULL }, WINED3D_GL_EXT_NONE },
5638 { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG), { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP), NULL }, WINED3D_GL_EXT_NONE },
5639 { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT), { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL }, WINED3D_GL_EXT_NONE },
5640 { STATE_PIXELSHADER, { STATE_PIXELSHADER, apply_pixelshader }, WINED3D_GL_EXT_NONE },
5641 { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE), { STATE_PIXELSHADER, NULL }, WINED3D_GL_EXT_NONE },
5642 { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR), state_texfactor }, WINED3D_GL_EXT_NONE },
5643 { STATE_RENDER(WINED3D_RS_FOGCOLOR), { STATE_RENDER(WINED3D_RS_FOGCOLOR), state_fogcolor }, WINED3D_GL_EXT_NONE },
5644 { STATE_RENDER(WINED3D_RS_FOGDENSITY), { STATE_RENDER(WINED3D_RS_FOGDENSITY), state_fogdensity }, WINED3D_GL_EXT_NONE },
5645 { STATE_RENDER(WINED3D_RS_FOGENABLE), { STATE_RENDER(WINED3D_RS_FOGENABLE), state_fog_fragpart }, WINED3D_GL_EXT_NONE },
5646 { STATE_RENDER(WINED3D_RS_FOGTABLEMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5647 { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE), { STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE },
5648 { STATE_RENDER(WINED3D_RS_FOGSTART), { STATE_RENDER(WINED3D_RS_FOGSTART), state_fogstartend }, WINED3D_GL_EXT_NONE },
5649 { STATE_RENDER(WINED3D_RS_FOGEND), { STATE_RENDER(WINED3D_RS_FOGSTART), NULL }, WINED3D_GL_EXT_NONE },
5650 { STATE_SAMPLER(0), { STATE_SAMPLER(0), sampler_texdim }, WINED3D_GL_EXT_NONE },
5651 { STATE_SAMPLER(1), { STATE_SAMPLER(1), sampler_texdim }, WINED3D_GL_EXT_NONE },
5652 { STATE_SAMPLER(2), { STATE_SAMPLER(2), sampler_texdim }, WINED3D_GL_EXT_NONE },
5653 { STATE_SAMPLER(3), { STATE_SAMPLER(3), sampler_texdim }, WINED3D_GL_EXT_NONE },
5654 { STATE_SAMPLER(4), { STATE_SAMPLER(4), sampler_texdim }, WINED3D_GL_EXT_NONE },
5655 { STATE_SAMPLER(5), { STATE_SAMPLER(5), sampler_texdim }, WINED3D_GL_EXT_NONE },
5656 { STATE_SAMPLER(6), { STATE_SAMPLER(6), sampler_texdim }, WINED3D_GL_EXT_NONE },
5657 { STATE_SAMPLER(7), { STATE_SAMPLER(7), sampler_texdim }, WINED3D_GL_EXT_NONE },
5658 {0 /* Terminate */, { 0, 0 }, WINED3D_GL_EXT_NONE },
5661 /* Context activation and GL locking are done by the caller. */
5662 static void ffp_enable(const struct wined3d_gl_info *gl_info, BOOL enable) {}
5664 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
5666 caps->PrimitiveMiscCaps = 0;
5667 caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
5668 | WINED3DTEXOPCAPS_ADDSIGNED
5669 | WINED3DTEXOPCAPS_ADDSIGNED2X
5670 | WINED3DTEXOPCAPS_MODULATE
5671 | WINED3DTEXOPCAPS_MODULATE2X
5672 | WINED3DTEXOPCAPS_MODULATE4X
5673 | WINED3DTEXOPCAPS_SELECTARG1
5674 | WINED3DTEXOPCAPS_SELECTARG2
5675 | WINED3DTEXOPCAPS_DISABLE;
5677 if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
5678 || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
5679 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5681 caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
5682 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
5683 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
5684 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
5685 | WINED3DTEXOPCAPS_LERP
5686 | WINED3DTEXOPCAPS_SUBTRACT;
5688 if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
5689 || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
5691 caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
5692 | WINED3DTEXOPCAPS_MULTIPLYADD
5693 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
5694 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
5695 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
5697 if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
5698 caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
5700 caps->MaxTextureBlendStages = gl_info->limits.textures;
5701 caps->MaxSimultaneousTextures = gl_info->limits.textures;
5704 static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; }
5705 static void ffp_fragment_free(struct wined3d_device *device) {}
5706 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
5708 if (TRACE_ON(d3d))
5710 TRACE("Checking support for fixup:\n");
5711 dump_color_fixup_desc(fixup);
5714 /* We only support identity conversions. */
5715 if (is_identity_fixup(fixup))
5717 TRACE("[OK]\n");
5718 return TRUE;
5721 TRACE("[FAILED]\n");
5722 return FALSE;
5725 const struct fragment_pipeline ffp_fragment_pipeline = {
5726 ffp_enable,
5727 ffp_fragment_get_caps,
5728 ffp_fragment_alloc,
5729 ffp_fragment_free,
5730 ffp_color_fixup_supported,
5731 ffp_fragmentstate_template,
5732 FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
5735 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
5737 unsigned int i;
5738 for(i = 0; funcs[i]; i++);
5739 return i;
5742 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5744 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5745 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5748 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
5750 context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
5751 context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
5752 context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
5755 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
5757 unsigned int start, last, i;
5759 start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
5760 last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
5761 for (i = start; i <= last; ++i)
5763 state_table[i].representative = 0;
5764 state_table[i].apply = state_undefined;
5767 start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
5768 last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
5769 for (i = start; i <= last; ++i)
5771 state_table[i].representative = 0;
5772 state_table[i].apply = state_undefined;
5775 start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
5776 last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
5777 for (i = start; i <= last; ++i)
5779 state_table[i].representative = 0;
5780 state_table[i].apply = state_undefined;
5784 static void validate_state_table(struct StateEntry *state_table)
5786 static const struct
5788 DWORD first;
5789 DWORD last;
5791 rs_holes[] =
5793 { 1, 1},
5794 { 3, 3},
5795 { 17, 18},
5796 { 21, 21},
5797 { 42, 45},
5798 { 47, 47},
5799 { 61, 127},
5800 {149, 150},
5801 {169, 169},
5802 {177, 177},
5803 {196, 197},
5804 { 0, 0},
5806 static const DWORD simple_states[] =
5808 STATE_MATERIAL,
5809 STATE_VDECL,
5810 STATE_STREAMSRC,
5811 STATE_INDEXBUFFER,
5812 STATE_VERTEXSHADERCONSTANT,
5813 STATE_PIXELSHADERCONSTANT,
5814 STATE_VSHADER,
5815 STATE_PIXELSHADER,
5816 STATE_VIEWPORT,
5817 STATE_SCISSORRECT,
5818 STATE_FRONTFACE,
5819 STATE_POINTSPRITECOORDORIGIN,
5820 STATE_BASEVERTEXINDEX,
5821 STATE_FRAMEBUFFER
5823 unsigned int i, current;
5825 for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
5827 if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
5829 if (!state_table[i].representative)
5830 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
5832 else if (state_table[i].representative)
5833 ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
5835 if (i == STATE_RENDER(rs_holes[current].last)) ++current;
5838 for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
5840 if (!state_table[simple_states[i]].representative)
5841 ERR("State %s (%#x) should have a representative.\n",
5842 debug_d3dstate(simple_states[i]), simple_states[i]);
5845 for (i = 0; i < STATE_HIGHEST + 1; ++i)
5847 DWORD rep = state_table[i].representative;
5848 if (rep)
5850 if (state_table[rep].representative != rep)
5852 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
5853 debug_d3dstate(i), i, debug_d3dstate(rep), rep);
5854 state_table[i].representative = 0;
5857 if (rep != i)
5859 if (state_table[i].apply)
5860 ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
5862 else if (!state_table[i].apply)
5864 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
5870 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
5871 const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
5872 const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
5874 unsigned int i, type, handlers;
5875 APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
5876 const struct StateEntryTemplate *cur;
5877 BOOL set[STATE_HIGHEST + 1];
5879 memset(multistate_funcs, 0, sizeof(multistate_funcs));
5881 for(i = 0; i < STATE_HIGHEST + 1; i++) {
5882 StateTable[i].representative = 0;
5883 StateTable[i].apply = state_undefined;
5886 for(type = 0; type < 3; type++) {
5887 /* This switch decides the order in which the states are applied */
5888 switch(type) {
5889 case 0: cur = misc; break;
5890 case 1: cur = fragment->states; break;
5891 case 2: cur = vertex; break;
5892 default: cur = NULL; /* Stupid compiler */
5894 if(!cur) continue;
5896 /* GL extension filtering should not prevent multiple handlers being applied from different
5897 * pipeline parts
5899 memset(set, 0, sizeof(set));
5901 for(i = 0; cur[i].state; i++) {
5902 APPLYSTATEFUNC *funcs_array;
5904 /* Only use the first matching state with the available extension from one template.
5905 * e.g.
5906 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
5907 * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0 }
5909 * if GL_XYZ_fancy is supported, ignore the 2nd line
5911 if(set[cur[i].state]) continue;
5912 /* Skip state lines depending on unsupported extensions */
5913 if (!gl_info->supported[cur[i].extension]) continue;
5914 set[cur[i].state] = TRUE;
5915 /* In some cases having an extension means that nothing has to be
5916 * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
5917 * supported, the texture coordinate fixup can be ignored. If the
5918 * apply function is used, mark the state set(done above) to prevent
5919 * applying later lines, but do not record anything in the state
5920 * table
5922 if (!cur[i].content.representative) continue;
5924 handlers = num_handlers(multistate_funcs[cur[i].state]);
5925 multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
5926 switch(handlers) {
5927 case 0:
5928 StateTable[cur[i].state].apply = cur[i].content.apply;
5929 break;
5930 case 1:
5931 StateTable[cur[i].state].apply = multistate_apply_2;
5932 dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
5934 sizeof(**dev_multistate_funcs) * 2);
5935 if (!dev_multistate_funcs[cur[i].state]) {
5936 goto out_of_mem;
5939 dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
5940 dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
5941 break;
5942 case 2:
5943 StateTable[cur[i].state].apply = multistate_apply_3;
5944 funcs_array = HeapReAlloc(GetProcessHeap(),
5946 dev_multistate_funcs[cur[i].state],
5947 sizeof(**dev_multistate_funcs) * 3);
5948 if (!funcs_array) {
5949 goto out_of_mem;
5952 dev_multistate_funcs[cur[i].state] = funcs_array;
5953 dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
5954 break;
5955 default:
5956 ERR("Unexpected amount of state handlers for state %u: %u\n",
5957 cur[i].state, handlers + 1);
5960 if(StateTable[cur[i].state].representative &&
5961 StateTable[cur[i].state].representative != cur[i].content.representative) {
5962 FIXME("State %u has different representatives in different pipeline parts\n",
5963 cur[i].state);
5965 StateTable[cur[i].state].representative = cur[i].content.representative;
5969 prune_invalid_states(StateTable, gl_info);
5970 validate_state_table(StateTable);
5972 return WINED3D_OK;
5974 out_of_mem:
5975 for (i = 0; i <= STATE_HIGHEST; ++i) {
5976 HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
5979 memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
5981 return E_OUTOFMEMORY;