VirtualBox

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

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

wine/new: export

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