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