VirtualBox

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

最後變更 在這個檔案從48073是 48073,由 vboxsync 提交於 12 年 前

wined3d: update to wine 1.6

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

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