VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine_new/wined3d/state.c@ 51313

Last change on this file since 51313 was 51313, checked in by vboxsync, 11 years ago

crOpenGL: bugfixes and work-arounds for wine issues

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette