ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

state.c
Go to the documentation of this file.
00001 /*
00002  * Direct3D state management
00003  *
00004  * Copyright 2002 Lionel Ulmer
00005  * Copyright 2002-2005 Jason Edmeades
00006  * Copyright 2003-2004 Raphael Junqueira
00007  * Copyright 2004 Christian Costa
00008  * Copyright 2005 Oliver Stieber
00009  * Copyright 2006 Henri Verbeet
00010  * Copyright 2006-2008 Stefan Dösinger for CodeWeavers
00011  * Copyright 2009-2011 Henri Verbeet for CodeWeavers
00012  *
00013  * This library is free software; you can redistribute it and/or
00014  * modify it under the terms of the GNU Lesser General Public
00015  * License as published by the Free Software Foundation; either
00016  * version 2.1 of the License, or (at your option) any later version.
00017  *
00018  * This library is distributed in the hope that it will be useful,
00019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021  * Lesser General Public License for more details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public
00024  * License along with this library; if not, write to the Free Software
00025  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00026  */
00027 
00028 #include "config.h"
00029 #include <stdio.h>
00030 #ifdef HAVE_FLOAT_H
00031 # include <float.h>
00032 #endif
00033 #include "wined3d_private.h"
00034 
00035 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
00036 WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
00037 
00038 /* GL locking for state handlers is done by the caller. */
00039 
00040 static void state_undefined(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00041 {
00042     ERR("Undefined state.\n");
00043 }
00044 
00045 static void state_nop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00046 {
00047     TRACE("%s: nop in current pipe config.\n", debug_d3dstate(state_id));
00048 }
00049 
00050 static void state_fillmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00051 {
00052     enum wined3d_fill_mode mode = state->render_states[WINED3D_RS_FILLMODE];
00053 
00054     switch (mode)
00055     {
00056         case WINED3D_FILL_POINT:
00057             glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
00058             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)");
00059             break;
00060         case WINED3D_FILL_WIREFRAME:
00061             glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00062             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)");
00063             break;
00064         case WINED3D_FILL_SOLID:
00065             glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00066             checkGLcall("glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)");
00067             break;
00068         default:
00069             FIXME("Unrecognized fill mode %#x.\n", mode);
00070     }
00071 }
00072 
00073 static void state_lighting(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00074 {
00075     /* Lighting is not enabled if transformed vertices are drawn, but lighting
00076      * does not affect the stream sources, so it is not grouped for
00077      * performance reasons. This state reads the decoded vertex declaration,
00078      * so if it is dirty don't do anything. The vertex declaration applying
00079      * function calls this function for updating. */
00080     if (isStateDirty(context, STATE_VDECL))
00081         return;
00082 
00083     if (state->render_states[WINED3D_RS_LIGHTING]
00084             && !context->swapchain->device->strided_streams.position_transformed)
00085     {
00086         glEnable(GL_LIGHTING);
00087         checkGLcall("glEnable GL_LIGHTING");
00088     } else {
00089         glDisable(GL_LIGHTING);
00090         checkGLcall("glDisable GL_LIGHTING");
00091     }
00092 }
00093 
00094 static void state_zenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00095 {
00096     /* No z test without depth stencil buffers */
00097     if (!state->fb->depth_stencil)
00098     {
00099         TRACE("No Z buffer - disabling depth test\n");
00100         glDisable(GL_DEPTH_TEST); /* This also disables z writing in gl */
00101         checkGLcall("glDisable GL_DEPTH_TEST");
00102         return;
00103     }
00104 
00105     switch (state->render_states[WINED3D_RS_ZENABLE])
00106     {
00107         case WINED3D_ZB_FALSE:
00108             glDisable(GL_DEPTH_TEST);
00109             checkGLcall("glDisable GL_DEPTH_TEST");
00110             break;
00111         case WINED3D_ZB_TRUE:
00112             glEnable(GL_DEPTH_TEST);
00113             checkGLcall("glEnable GL_DEPTH_TEST");
00114             break;
00115         case WINED3D_ZB_USEW:
00116             glEnable(GL_DEPTH_TEST);
00117             checkGLcall("glEnable GL_DEPTH_TEST");
00118             FIXME("W buffer is not well handled\n");
00119             break;
00120         default:
00121             FIXME("Unrecognized depth buffer type %#x.\n",
00122                     state->render_states[WINED3D_RS_ZENABLE]);
00123     }
00124 }
00125 
00126 static void state_cullmode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00127 {
00128     /* glFrontFace() is set in context.c at context init and on an
00129      * offscreen / onscreen rendering switch. */
00130     switch (state->render_states[WINED3D_RS_CULLMODE])
00131     {
00132         case WINED3D_CULL_NONE:
00133             glDisable(GL_CULL_FACE);
00134             checkGLcall("glDisable GL_CULL_FACE");
00135             break;
00136         case WINED3D_CULL_CW:
00137             glEnable(GL_CULL_FACE);
00138             checkGLcall("glEnable GL_CULL_FACE");
00139             glCullFace(GL_FRONT);
00140             checkGLcall("glCullFace(GL_FRONT)");
00141             break;
00142         case WINED3D_CULL_CCW:
00143             glEnable(GL_CULL_FACE);
00144             checkGLcall("glEnable GL_CULL_FACE");
00145             glCullFace(GL_BACK);
00146             checkGLcall("glCullFace(GL_BACK)");
00147             break;
00148         default:
00149             FIXME("Unrecognized cull mode %#x.\n",
00150                     state->render_states[WINED3D_RS_CULLMODE]);
00151     }
00152 }
00153 
00154 static void state_shademode(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00155 {
00156     switch (state->render_states[WINED3D_RS_SHADEMODE])
00157     {
00158         case WINED3D_SHADE_FLAT:
00159             glShadeModel(GL_FLAT);
00160             checkGLcall("glShadeModel(GL_FLAT)");
00161             break;
00162         case WINED3D_SHADE_GOURAUD:
00163             glShadeModel(GL_SMOOTH);
00164             checkGLcall("glShadeModel(GL_SMOOTH)");
00165             break;
00166         case WINED3D_SHADE_PHONG:
00167             FIXME("WINED3D_SHADE_PHONG isn't supported.\n");
00168             break;
00169         default:
00170             FIXME("Unrecognized shade mode %#x.\n",
00171                     state->render_states[WINED3D_RS_SHADEMODE]);
00172     }
00173 }
00174 
00175 static void state_ditherenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00176 {
00177     if (state->render_states[WINED3D_RS_DITHERENABLE])
00178     {
00179         glEnable(GL_DITHER);
00180         checkGLcall("glEnable GL_DITHER");
00181     }
00182     else
00183     {
00184         glDisable(GL_DITHER);
00185         checkGLcall("glDisable GL_DITHER");
00186     }
00187 }
00188 
00189 static void state_zwritenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00190 {
00191     /* TODO: Test if in d3d z writing is enabled even if ZENABLE is off.
00192      * If yes, this has to be merged with ZENABLE and ZFUNC. */
00193     if (state->render_states[WINED3D_RS_ZWRITEENABLE])
00194     {
00195         glDepthMask(1);
00196         checkGLcall("glDepthMask(1)");
00197     }
00198     else
00199     {
00200         glDepthMask(0);
00201         checkGLcall("glDepthMask(0)");
00202     }
00203 }
00204 
00205 static GLenum gl_compare_func(enum wined3d_cmp_func f)
00206 {
00207     switch (f)
00208     {
00209         case WINED3D_CMP_NEVER:
00210             return GL_NEVER;
00211         case WINED3D_CMP_LESS:
00212             return GL_LESS;
00213         case WINED3D_CMP_EQUAL:
00214             return GL_EQUAL;
00215         case WINED3D_CMP_LESSEQUAL:
00216             return GL_LEQUAL;
00217         case WINED3D_CMP_GREATER:
00218             return GL_GREATER;
00219         case WINED3D_CMP_NOTEQUAL:
00220             return GL_NOTEQUAL;
00221         case WINED3D_CMP_GREATEREQUAL:
00222             return GL_GEQUAL;
00223         case WINED3D_CMP_ALWAYS:
00224             return GL_ALWAYS;
00225         default:
00226             FIXME("Unrecognized compare function %#x.\n", f);
00227             return GL_NONE;
00228     }
00229 }
00230 
00231 static void state_zfunc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00232 {
00233     GLenum depth_func = gl_compare_func(state->render_states[WINED3D_RS_ZFUNC]);
00234 
00235     if (!depth_func) return;
00236 
00237     if (depth_func == GL_EQUAL || depth_func == GL_NOTEQUAL)
00238     {
00239         static BOOL once;
00240         /* There are a few issues with this: First, our inability to
00241          * select a proper Z depth, most of the time we're stuck with
00242          * D24S8, even if the app selects D32 or D16. There seem to be
00243          * some other precision problems which have to be debugged to
00244          * make NOTEQUAL and EQUAL work properly. */
00245         if (!once)
00246         {
00247             once = TRUE;
00248             FIXME("D3DCMP_NOTEQUAL and D3DCMP_EQUAL do not work correctly yet.\n");
00249         }
00250     }
00251 
00252     glDepthFunc(depth_func);
00253     checkGLcall("glDepthFunc");
00254 }
00255 
00256 static void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00257 {
00258     float col[4];
00259 
00260     D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_AMBIENT], col);
00261     TRACE("Setting ambient to (%f,%f,%f,%f)\n", col[0], col[1], col[2], col[3]);
00262     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
00263     checkGLcall("glLightModel for MODEL_AMBIENT");
00264 }
00265 
00266 static void state_blendop_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00267 {
00268     WARN("Unsupported in local OpenGL implementation: glBlendEquation\n");
00269 }
00270 
00271 static GLenum gl_blend_op(enum wined3d_blend_op op)
00272 {
00273     switch (op)
00274     {
00275         case WINED3D_BLEND_OP_ADD:
00276             return GL_FUNC_ADD_EXT;
00277         case WINED3D_BLEND_OP_SUBTRACT:
00278             return GL_FUNC_SUBTRACT_EXT;
00279         case WINED3D_BLEND_OP_REVSUBTRACT:
00280             return GL_FUNC_REVERSE_SUBTRACT_EXT;
00281         case WINED3D_BLEND_OP_MIN:
00282             return GL_MIN_EXT;
00283         case WINED3D_BLEND_OP_MAX:
00284             return GL_MAX_EXT;
00285         default:
00286             FIXME("Unhandled blend op %#x.\n", op);
00287             return GL_NONE;
00288     }
00289 }
00290 
00291 static void state_blendop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00292 {
00293     const struct wined3d_gl_info *gl_info = context->gl_info;
00294     GLenum blend_equation_alpha = GL_FUNC_ADD_EXT;
00295     GLenum blend_equation = GL_FUNC_ADD_EXT;
00296 
00297     /* BLENDOPALPHA requires GL_EXT_blend_equation_separate, so make sure it is around */
00298     if (state->render_states[WINED3D_RS_BLENDOPALPHA]
00299             && !gl_info->supported[EXT_BLEND_EQUATION_SEPARATE])
00300     {
00301         WARN("Unsupported in local OpenGL implementation: glBlendEquationSeparateEXT\n");
00302         return;
00303     }
00304 
00305     blend_equation = gl_blend_op(state->render_states[WINED3D_RS_BLENDOP]);
00306     blend_equation_alpha = gl_blend_op(state->render_states[WINED3D_RS_BLENDOPALPHA]);
00307     TRACE("blend_equation %#x, blend_equation_alpha %#x.\n", blend_equation, blend_equation_alpha);
00308 
00309     if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
00310     {
00311         GL_EXTCALL(glBlendEquationSeparateEXT(blend_equation, blend_equation_alpha));
00312         checkGLcall("glBlendEquationSeparateEXT");
00313     }
00314     else
00315     {
00316         GL_EXTCALL(glBlendEquationEXT(blend_equation));
00317         checkGLcall("glBlendEquation");
00318     }
00319 }
00320 
00321 static GLenum gl_blend_factor(enum wined3d_blend factor, const struct wined3d_format *dst_format)
00322 {
00323     switch (factor)
00324     {
00325         case WINED3D_BLEND_ZERO:
00326             return GL_ZERO;
00327         case WINED3D_BLEND_ONE:
00328             return GL_ONE;
00329         case WINED3D_BLEND_SRCCOLOR:
00330             return GL_SRC_COLOR;
00331         case WINED3D_BLEND_INVSRCCOLOR:
00332             return GL_ONE_MINUS_SRC_COLOR;
00333         case WINED3D_BLEND_SRCALPHA:
00334             return GL_SRC_ALPHA;
00335         case WINED3D_BLEND_INVSRCALPHA:
00336             return GL_ONE_MINUS_SRC_ALPHA;
00337         case WINED3D_BLEND_DESTCOLOR:
00338             return GL_DST_COLOR;
00339         case WINED3D_BLEND_INVDESTCOLOR:
00340             return GL_ONE_MINUS_DST_COLOR;
00341         /* To compensate for the lack of format switching with backbuffer
00342          * offscreen rendering, and with onscreen rendering, we modify the
00343          * alpha test parameters for (INV)DESTALPHA if the render target
00344          * doesn't support alpha blending. A nonexistent alpha channel
00345          * returns 1.0, so WINED3D_BLEND_DESTALPHA becomes GL_ONE, and
00346          * WINED3D_BLEND_INVDESTALPHA becomes GL_ZERO. */
00347         case WINED3D_BLEND_DESTALPHA:
00348             return dst_format->alpha_mask ? GL_DST_ALPHA : GL_ONE;
00349         case WINED3D_BLEND_INVDESTALPHA:
00350             return dst_format->alpha_mask ? GL_ONE_MINUS_DST_ALPHA : GL_ZERO;
00351         case WINED3D_BLEND_SRCALPHASAT:
00352             return GL_SRC_ALPHA_SATURATE;
00353         case WINED3D_BLEND_BLENDFACTOR:
00354             return GL_CONSTANT_COLOR_EXT;
00355         case WINED3D_BLEND_INVBLENDFACTOR:
00356             return GL_ONE_MINUS_CONSTANT_COLOR_EXT;
00357         default:
00358             FIXME("Unhandled blend factor %#x.\n", factor);
00359             return GL_NONE;
00360     }
00361 }
00362 
00363 static void state_blend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00364 {
00365     const struct wined3d_surface *target = state->fb->render_targets[0];
00366     const struct wined3d_gl_info *gl_info = context->gl_info;
00367     GLenum srcBlend, dstBlend;
00368     enum wined3d_blend d3d_blend;
00369 
00370     /* According to the red book, GL_LINE_SMOOTH needs GL_BLEND with specific
00371      * blending parameters to work. */
00372     if (state->render_states[WINED3D_RS_ALPHABLENDENABLE]
00373             || state->render_states[WINED3D_RS_EDGEANTIALIAS]
00374             || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
00375     {
00376         /* Disable blending in all cases even without pixelshaders.
00377          * With blending on we could face a big performance penalty.
00378          * The d3d9 visual test confirms the behavior. */
00379         if (context->render_offscreen
00380                 && !(target->resource.format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING))
00381         {
00382             glDisable(GL_BLEND);
00383             checkGLcall("glDisable GL_BLEND");
00384             return;
00385         } else {
00386             glEnable(GL_BLEND);
00387             checkGLcall("glEnable GL_BLEND");
00388         }
00389     } else {
00390         glDisable(GL_BLEND);
00391         checkGLcall("glDisable GL_BLEND");
00392         /* Nothing more to do - get out */
00393         return;
00394     };
00395 
00396     /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
00397      * source blending values which are still valid up to d3d9. They should
00398      * not occur as dest blend values. */
00399     d3d_blend = state->render_states[WINED3D_RS_SRCBLEND];
00400     if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
00401     {
00402         srcBlend = GL_SRC_ALPHA;
00403         dstBlend = GL_ONE_MINUS_SRC_ALPHA;
00404     }
00405     else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
00406     {
00407         srcBlend = GL_ONE_MINUS_SRC_ALPHA;
00408         dstBlend = GL_SRC_ALPHA;
00409     }
00410     else
00411     {
00412         srcBlend = gl_blend_factor(d3d_blend, target->resource.format);
00413         dstBlend = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLEND],
00414                 target->resource.format);
00415     }
00416 
00417     if (state->render_states[WINED3D_RS_EDGEANTIALIAS]
00418             || state->render_states[WINED3D_RS_ANTIALIASEDLINEENABLE])
00419     {
00420         glEnable(GL_LINE_SMOOTH);
00421         checkGLcall("glEnable(GL_LINE_SMOOTH)");
00422         if(srcBlend != GL_SRC_ALPHA) {
00423             WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected src blending param\n");
00424         }
00425         if(dstBlend != GL_ONE_MINUS_SRC_ALPHA && dstBlend != GL_ONE) {
00426             WARN("WINED3D_RS_EDGEANTIALIAS enabled, but unexpected dst blending param\n");
00427         }
00428     } else {
00429         glDisable(GL_LINE_SMOOTH);
00430         checkGLcall("glDisable(GL_LINE_SMOOTH)");
00431     }
00432 
00433     /* Re-apply BLENDOP(ALPHA) because of a possible SEPARATEALPHABLENDENABLE change */
00434     if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_BLENDOP)))
00435         state_blendop(context, state, STATE_RENDER(WINED3D_RS_BLENDOPALPHA));
00436 
00437     if (state->render_states[WINED3D_RS_SEPARATEALPHABLENDENABLE])
00438     {
00439         GLenum srcBlendAlpha, dstBlendAlpha;
00440 
00441         /* Separate alpha blending requires GL_EXT_blend_function_separate, so make sure it is around */
00442         if (!context->gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
00443         {
00444             WARN("Unsupported in local OpenGL implementation: glBlendFuncSeparateEXT\n");
00445             return;
00446         }
00447 
00448         /* WINED3D_BLEND_BOTHSRCALPHA and WINED3D_BLEND_BOTHINVSRCALPHA are legacy
00449          * source blending values which are still valid up to d3d9. They should
00450          * not occur as dest blend values. */
00451         d3d_blend = state->render_states[WINED3D_RS_SRCBLENDALPHA];
00452         if (d3d_blend == WINED3D_BLEND_BOTHSRCALPHA)
00453         {
00454             srcBlendAlpha = GL_SRC_ALPHA;
00455             dstBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
00456         }
00457         else if (d3d_blend == WINED3D_BLEND_BOTHINVSRCALPHA)
00458         {
00459             srcBlendAlpha = GL_ONE_MINUS_SRC_ALPHA;
00460             dstBlendAlpha = GL_SRC_ALPHA;
00461         }
00462         else
00463         {
00464             srcBlendAlpha = gl_blend_factor(d3d_blend, target->resource.format);
00465             dstBlendAlpha = gl_blend_factor(state->render_states[WINED3D_RS_DESTBLENDALPHA],
00466                     target->resource.format);
00467         }
00468 
00469         GL_EXTCALL(glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha));
00470         checkGLcall("glBlendFuncSeparateEXT");
00471     } else {
00472         TRACE("glBlendFunc src=%x, dst=%x\n", srcBlend, dstBlend);
00473         glBlendFunc(srcBlend, dstBlend);
00474         checkGLcall("glBlendFunc");
00475     }
00476 
00477     /* Colorkey fixup for stage 0 alphaop depends on
00478      * WINED3D_RS_ALPHABLENDENABLE state, so it may need updating. */
00479     if (state->render_states[WINED3D_RS_COLORKEYENABLE])
00480         context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
00481 }
00482 
00483 static void state_blendfactor_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00484 {
00485     WARN("Unsupported in local OpenGL implementation: glBlendColorEXT\n");
00486 }
00487 
00488 static void state_blendfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00489 {
00490     const struct wined3d_gl_info *gl_info = context->gl_info;
00491     float col[4];
00492 
00493     TRACE("Setting blend factor to %#x.\n", state->render_states[WINED3D_RS_BLENDFACTOR]);
00494 
00495     D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_BLENDFACTOR], col);
00496     GL_EXTCALL(glBlendColorEXT (col[0],col[1],col[2],col[3]));
00497     checkGLcall("glBlendColor");
00498 }
00499 
00500 static void state_alpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00501 {
00502     int glParm = 0;
00503     float ref;
00504     BOOL enable_ckey = FALSE;
00505 
00506     TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
00507 
00508     /* Find out if the texture on the first stage has a ckey set
00509      * The alpha state func reads the texture settings, even though alpha and texture are not grouped
00510      * together. This is to avoid making a huge alpha+texture+texture stage+ckey block due to the hardly
00511      * used WINED3D_RS_COLORKEYENABLE state(which is d3d <= 3 only). The texture function will call alpha
00512      * in case it finds some texture+colorkeyenable combination which needs extra care.
00513      */
00514     if (state->textures[0])
00515     {
00516         struct wined3d_texture *texture = state->textures[0];
00517         GLenum texture_dimensions = texture->target;
00518 
00519         if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
00520         {
00521             struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
00522 
00523             if (surf->CKeyFlags & WINEDDSD_CKSRCBLT)
00524             {
00525                 /* The surface conversion does not do color keying conversion for surfaces that have an alpha
00526                  * channel on their own. Likewise, the alpha test shouldn't be set up for color keying if the
00527                  * surface has alpha bits */
00528                 if (!surf->resource.format->alpha_mask) enable_ckey = TRUE;
00529             }
00530         }
00531     }
00532 
00533     if (enable_ckey || context->last_was_ckey)
00534         context_apply_state(context, state, STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP));
00535     context->last_was_ckey = enable_ckey;
00536 
00537     if (state->render_states[WINED3D_RS_ALPHATESTENABLE]
00538             || (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey))
00539     {
00540         glEnable(GL_ALPHA_TEST);
00541         checkGLcall("glEnable GL_ALPHA_TEST");
00542     } else {
00543         glDisable(GL_ALPHA_TEST);
00544         checkGLcall("glDisable GL_ALPHA_TEST");
00545         /* Alpha test is disabled, don't bother setting the params - it will happen on the next
00546          * enable call
00547          */
00548         return;
00549     }
00550 
00551     if (state->render_states[WINED3D_RS_COLORKEYENABLE] && enable_ckey)
00552     {
00553         glParm = GL_NOTEQUAL;
00554         ref = 0.0f;
00555     }
00556     else
00557     {
00558         ref = ((float)state->render_states[WINED3D_RS_ALPHAREF]) / 255.0f;
00559         glParm = gl_compare_func(state->render_states[WINED3D_RS_ALPHAFUNC]);
00560     }
00561     if(glParm) {
00562         glAlphaFunc(glParm, ref);
00563         checkGLcall("glAlphaFunc");
00564     }
00565 }
00566 
00567 static void shaderconstant(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00568 {
00569     const struct wined3d_device *device = context->swapchain->device;
00570 
00571     /* Vertex and pixel shader states will call a shader upload, don't do
00572      * anything as long one of them has an update pending. */
00573     if (isStateDirty(context, STATE_VDECL)
00574             || isStateDirty(context, STATE_PIXELSHADER))
00575        return;
00576 
00577     device->shader_backend->shader_load_constants(context, use_ps(state), use_vs(state));
00578 }
00579 
00580 static void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00581 {
00582     DWORD enable  = 0xFFFFFFFF;
00583     DWORD disable = 0x00000000;
00584 
00585     if (use_vs(state))
00586     {
00587         const struct wined3d_device *device = context->swapchain->device;
00588 
00589         if (!device->vs_clipping)
00590         {
00591             /* The spec says that opengl clipping planes are disabled when using shaders. Direct3D planes aren't,
00592              * so that is an issue. The MacOS ATI driver keeps clipping planes activated with shaders in some
00593              * conditions I got sick of tracking down. The shader state handler disables all clip planes because
00594              * of that - don't do anything here and keep them disabled
00595              */
00596             if (state->render_states[WINED3D_RS_CLIPPLANEENABLE])
00597             {
00598                 static BOOL warned = FALSE;
00599                 if(!warned) {
00600                     FIXME("Clipping not supported with vertex shaders\n");
00601                     warned = TRUE;
00602                 }
00603             }
00604             return;
00605         }
00606 
00607         /* glEnable(GL_CLIP_PLANEx) doesn't apply to vertex shaders. The enabled / disabled planes are
00608          * hardcoded into the shader. Update the shader to update the enabled clipplanes */
00609         if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
00610         {
00611             device->shader_backend->shader_select(context, use_ps(state), TRUE);
00612             if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
00613                 shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
00614         }
00615     }
00616 
00617     /* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
00618      * of already set values
00619      */
00620 
00621     /* If enabling / disabling all
00622      * TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
00623      */
00624     if (state->render_states[WINED3D_RS_CLIPPING])
00625     {
00626         enable = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
00627         disable = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
00628     }
00629     else
00630     {
00631         disable = 0xffffffff;
00632         enable  = 0x00;
00633     }
00634 
00635     if (enable & WINED3DCLIPPLANE0)  { glEnable(GL_CLIP_PLANE0);  checkGLcall("glEnable(clip plane 0)"); }
00636     if (enable & WINED3DCLIPPLANE1)  { glEnable(GL_CLIP_PLANE1);  checkGLcall("glEnable(clip plane 1)"); }
00637     if (enable & WINED3DCLIPPLANE2)  { glEnable(GL_CLIP_PLANE2);  checkGLcall("glEnable(clip plane 2)"); }
00638     if (enable & WINED3DCLIPPLANE3)  { glEnable(GL_CLIP_PLANE3);  checkGLcall("glEnable(clip plane 3)"); }
00639     if (enable & WINED3DCLIPPLANE4)  { glEnable(GL_CLIP_PLANE4);  checkGLcall("glEnable(clip plane 4)"); }
00640     if (enable & WINED3DCLIPPLANE5)  { glEnable(GL_CLIP_PLANE5);  checkGLcall("glEnable(clip plane 5)"); }
00641 
00642     if (disable & WINED3DCLIPPLANE0) { glDisable(GL_CLIP_PLANE0); checkGLcall("glDisable(clip plane 0)"); }
00643     if (disable & WINED3DCLIPPLANE1) { glDisable(GL_CLIP_PLANE1); checkGLcall("glDisable(clip plane 1)"); }
00644     if (disable & WINED3DCLIPPLANE2) { glDisable(GL_CLIP_PLANE2); checkGLcall("glDisable(clip plane 2)"); }
00645     if (disable & WINED3DCLIPPLANE3) { glDisable(GL_CLIP_PLANE3); checkGLcall("glDisable(clip plane 3)"); }
00646     if (disable & WINED3DCLIPPLANE4) { glDisable(GL_CLIP_PLANE4); checkGLcall("glDisable(clip plane 4)"); }
00647     if (disable & WINED3DCLIPPLANE5) { glDisable(GL_CLIP_PLANE5); checkGLcall("glDisable(clip plane 5)"); }
00648 }
00649 
00650 static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00651 {
00652     const struct wined3d_gl_info *gl_info = context->gl_info;
00653     /* Originally this used glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR)
00654      * and (GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR) to swap between enabled/disabled
00655      * specular color. This is wrong:
00656      * Separate specular color means the specular colour is maintained separately, whereas
00657      * single color means it is merged in. However in both cases they are being used to
00658      * some extent.
00659      * To disable specular color, set it explicitly to black and turn off GL_COLOR_SUM_EXT
00660      * NOTE: If not supported don't give FIXMEs the impact is really minimal and very few people are
00661      * running 1.4 yet!
00662      *
00663      *
00664      * If register combiners are enabled, enabling / disabling GL_COLOR_SUM has no effect.
00665      * Instead, we need to setup the FinalCombiner properly.
00666      *
00667      * The default setup for the FinalCombiner is:
00668      *
00669      * <variable>       <input>                             <mapping>               <usage>
00670      * GL_VARIABLE_A_NV GL_FOG,                             GL_UNSIGNED_IDENTITY_NV GL_ALPHA
00671      * GL_VARIABLE_B_NV GL_SPARE0_PLUS_SECONDARY_COLOR_NV   GL_UNSIGNED_IDENTITY_NV GL_RGB
00672      * GL_VARIABLE_C_NV GL_FOG                              GL_UNSIGNED_IDENTITY_NV GL_RGB
00673      * GL_VARIABLE_D_NV GL_ZERO                             GL_UNSIGNED_IDENTITY_NV GL_RGB
00674      * GL_VARIABLE_E_NV GL_ZERO                             GL_UNSIGNED_IDENTITY_NV GL_RGB
00675      * GL_VARIABLE_F_NV GL_ZERO                             GL_UNSIGNED_IDENTITY_NV GL_RGB
00676      * GL_VARIABLE_G_NV GL_SPARE0_NV                        GL_UNSIGNED_IDENTITY_NV GL_ALPHA
00677      *
00678      * That's pretty much fine as it is, except for variable B, which needs to take
00679      * either GL_SPARE0_PLUS_SECONDARY_COLOR_NV or GL_SPARE0_NV, depending on
00680      * whether WINED3D_RS_SPECULARENABLE is enabled or not.
00681      */
00682 
00683     TRACE("Setting specular enable state and materials\n");
00684     if (state->render_states[WINED3D_RS_SPECULARENABLE])
00685     {
00686         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
00687         checkGLcall("glMaterialfv");
00688 
00689         if (state->material.power > gl_info->limits.shininess)
00690         {
00691             /* glMaterialf man page says that the material says that GL_SHININESS must be between 0.0
00692              * and 128.0, although in d3d neither -1 nor 129 produce an error. GL_NV_max_light_exponent
00693              * allows bigger values. If the extension is supported, gl_info->limits.shininess contains the
00694              * value reported by the extension, otherwise 128. For values > gl_info->limits.shininess clamp
00695              * them, it should be safe to do so without major visual distortions.
00696              */
00697             WARN("Material power = %.8e, limit %.8e\n", state->material.power, gl_info->limits.shininess);
00698             glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, gl_info->limits.shininess);
00699         }
00700         else
00701         {
00702             glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, state->material.power);
00703         }
00704         checkGLcall("glMaterialf(GL_SHININESS)");
00705 
00706         if (gl_info->supported[EXT_SECONDARY_COLOR])
00707         {
00708             glEnable(GL_COLOR_SUM_EXT);
00709         }
00710         else
00711         {
00712             TRACE("Specular colors cannot be enabled in this version of opengl\n");
00713         }
00714         checkGLcall("glEnable(GL_COLOR_SUM)");
00715 
00716         if (gl_info->supported[NV_REGISTER_COMBINERS])
00717         {
00718             GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_PLUS_SECONDARY_COLOR_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
00719             checkGLcall("glFinalCombinerInputNV()");
00720         }
00721     } else {
00722         static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
00723 
00724         /* for the case of enabled lighting: */
00725         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
00726         checkGLcall("glMaterialfv");
00727 
00728         /* for the case of disabled lighting: */
00729         if (gl_info->supported[EXT_SECONDARY_COLOR])
00730         {
00731             glDisable(GL_COLOR_SUM_EXT);
00732         }
00733         else
00734         {
00735             TRACE("Specular colors cannot be disabled in this version of opengl\n");
00736         }
00737         checkGLcall("glDisable(GL_COLOR_SUM)");
00738 
00739         if (gl_info->supported[NV_REGISTER_COMBINERS])
00740         {
00741             GL_EXTCALL(glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB));
00742             checkGLcall("glFinalCombinerInputNV()");
00743         }
00744     }
00745 
00746     TRACE("diffuse {%.8e, %.8e, %.8e, %.8e}\n",
00747             state->material.diffuse.r, state->material.diffuse.g,
00748             state->material.diffuse.b, state->material.diffuse.a);
00749     TRACE("ambient {%.8e, %.8e, %.8e, %.8e}\n",
00750             state->material.ambient.r, state->material.ambient.g,
00751             state->material.ambient.b, state->material.ambient.a);
00752     TRACE("specular {%.8e, %.8e, %.8e, %.8e}\n",
00753             state->material.specular.r, state->material.specular.g,
00754             state->material.specular.b, state->material.specular.a);
00755     TRACE("emissive {%.8e, %.8e, %.8e, %.8e}\n",
00756             state->material.emissive.r, state->material.emissive.g,
00757             state->material.emissive.b, state->material.emissive.a);
00758 
00759     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
00760     checkGLcall("glMaterialfv(GL_AMBIENT)");
00761     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
00762     checkGLcall("glMaterialfv(GL_DIFFUSE)");
00763     glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
00764     checkGLcall("glMaterialfv(GL_EMISSION)");
00765 }
00766 
00767 static void state_texfactor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00768 {
00769     const struct wined3d_gl_info *gl_info = context->gl_info;
00770     unsigned int i;
00771 
00772     /* Note the texture color applies to all textures whereas
00773      * GL_TEXTURE_ENV_COLOR applies to active only. */
00774     float col[4];
00775     D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_TEXTUREFACTOR], col);
00776 
00777     /* And now the default texture color as well */
00778     for (i = 0; i < gl_info->limits.texture_stages; ++i)
00779     {
00780         /* Note the WINED3D_RS value applies to all textures, but GL has one
00781          * per texture, so apply it now ready to be used! */
00782         context_active_texture(context, gl_info, i);
00783 
00784         glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, &col[0]);
00785         checkGLcall("glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);");
00786     }
00787 }
00788 
00789 static void renderstate_stencil_twosided(struct wined3d_context *context, GLint face,
00790         GLint func, GLint ref, GLuint mask, GLint stencilFail, GLint depthFail, GLint stencilPass)
00791 {
00792     const struct wined3d_gl_info *gl_info = context->gl_info;
00793 
00794     glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
00795     checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
00796     GL_EXTCALL(glActiveStencilFaceEXT(face));
00797     checkGLcall("glActiveStencilFaceEXT(...)");
00798     glStencilFunc(func, ref, mask);
00799     checkGLcall("glStencilFunc(...)");
00800     glStencilOp(stencilFail, depthFail, stencilPass);
00801     checkGLcall("glStencilOp(...)");
00802 }
00803 
00804 static GLenum gl_stencil_op(enum wined3d_stencil_op op)
00805 {
00806     switch (op)
00807     {
00808         case WINED3D_STENCIL_OP_KEEP:
00809             return GL_KEEP;
00810         case WINED3D_STENCIL_OP_ZERO:
00811             return GL_ZERO;
00812         case WINED3D_STENCIL_OP_REPLACE:
00813             return GL_REPLACE;
00814         case WINED3D_STENCIL_OP_INCR_SAT:
00815             return GL_INCR;
00816         case WINED3D_STENCIL_OP_DECR_SAT:
00817             return GL_DECR;
00818         case WINED3D_STENCIL_OP_INVERT:
00819             return GL_INVERT;
00820         case WINED3D_STENCIL_OP_INCR:
00821             return GL_INCR_WRAP_EXT;
00822         case WINED3D_STENCIL_OP_DECR:
00823             return GL_DECR_WRAP_EXT;
00824         default:
00825             FIXME("Unrecognized stencil op %#x.\n", op);
00826             return GL_KEEP;
00827     }
00828 }
00829 
00830 static void state_stencil(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00831 {
00832     const struct wined3d_gl_info *gl_info = context->gl_info;
00833     DWORD onesided_enable = FALSE;
00834     DWORD twosided_enable = FALSE;
00835     GLint func = GL_ALWAYS;
00836     GLint func_ccw = GL_ALWAYS;
00837     GLint ref = 0;
00838     GLuint mask = 0;
00839     GLint stencilFail = GL_KEEP;
00840     GLint depthFail = GL_KEEP;
00841     GLint stencilPass = GL_KEEP;
00842     GLint stencilFail_ccw = GL_KEEP;
00843     GLint depthFail_ccw = GL_KEEP;
00844     GLint stencilPass_ccw = GL_KEEP;
00845 
00846     /* No stencil test without a stencil buffer. */
00847     if (!state->fb->depth_stencil)
00848     {
00849         glDisable(GL_STENCIL_TEST);
00850         checkGLcall("glDisable GL_STENCIL_TEST");
00851         return;
00852     }
00853 
00854     onesided_enable = state->render_states[WINED3D_RS_STENCILENABLE];
00855     twosided_enable = state->render_states[WINED3D_RS_TWOSIDEDSTENCILMODE];
00856     if (!(func = gl_compare_func(state->render_states[WINED3D_RS_STENCILFUNC])))
00857         func = GL_ALWAYS;
00858     if (!(func_ccw = gl_compare_func(state->render_states[WINED3D_RS_CCW_STENCILFUNC])))
00859         func_ccw = GL_ALWAYS;
00860     ref = state->render_states[WINED3D_RS_STENCILREF];
00861     mask = state->render_states[WINED3D_RS_STENCILMASK];
00862     stencilFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILFAIL]);
00863     depthFail = gl_stencil_op(state->render_states[WINED3D_RS_STENCILZFAIL]);
00864     stencilPass = gl_stencil_op(state->render_states[WINED3D_RS_STENCILPASS]);
00865     stencilFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILFAIL]);
00866     depthFail_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILZFAIL]);
00867     stencilPass_ccw = gl_stencil_op(state->render_states[WINED3D_RS_CCW_STENCILPASS]);
00868 
00869     TRACE("(onesided %d, twosided %d, ref %x, mask %x, "
00870           "GL_FRONT: func: %x, fail %x, zfail %x, zpass %x "
00871           "GL_BACK: func: %x, fail %x, zfail %x, zpass %x )\n",
00872     onesided_enable, twosided_enable, ref, mask,
00873     func, stencilFail, depthFail, stencilPass,
00874     func_ccw, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
00875 
00876     if (twosided_enable && onesided_enable) {
00877         glEnable(GL_STENCIL_TEST);
00878         checkGLcall("glEnable GL_STENCIL_TEST");
00879 
00880         if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
00881         {
00882             /* Apply back first, then front. This function calls glActiveStencilFaceEXT,
00883              * which has an effect on the code below too. If we apply the front face
00884              * afterwards, we are sure that the active stencil face is set to front,
00885              * and other stencil functions which do not use two sided stencil do not have
00886              * to set it back
00887              */
00888             renderstate_stencil_twosided(context, GL_BACK,
00889                     func_ccw, ref, mask, stencilFail_ccw, depthFail_ccw, stencilPass_ccw);
00890             renderstate_stencil_twosided(context, GL_FRONT,
00891                     func, ref, mask, stencilFail, depthFail, stencilPass);
00892         }
00893         else if (gl_info->supported[ATI_SEPARATE_STENCIL])
00894         {
00895             GL_EXTCALL(glStencilFuncSeparateATI(func, func_ccw, ref, mask));
00896             checkGLcall("glStencilFuncSeparateATI(...)");
00897             GL_EXTCALL(glStencilOpSeparateATI(GL_FRONT, stencilFail, depthFail, stencilPass));
00898             checkGLcall("glStencilOpSeparateATI(GL_FRONT, ...)");
00899             GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail_ccw, depthFail_ccw, stencilPass_ccw));
00900             checkGLcall("glStencilOpSeparateATI(GL_BACK, ...)");
00901         } else {
00902             ERR("Separate (two sided) stencil not supported on this version of opengl. Caps weren't honored?\n");
00903         }
00904     }
00905     else if(onesided_enable)
00906     {
00907         if (gl_info->supported[EXT_STENCIL_TWO_SIDE])
00908         {
00909             glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
00910             checkGLcall("glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT)");
00911         }
00912 
00913         /* This code disables the ATI extension as well, since the standard stencil functions are equal
00914          * to calling the ATI functions with GL_FRONT_AND_BACK as face parameter
00915          */
00916         glEnable(GL_STENCIL_TEST);
00917         checkGLcall("glEnable GL_STENCIL_TEST");
00918         glStencilFunc(func, ref, mask);
00919         checkGLcall("glStencilFunc(...)");
00920         glStencilOp(stencilFail, depthFail, stencilPass);
00921         checkGLcall("glStencilOp(...)");
00922     } else {
00923         glDisable(GL_STENCIL_TEST);
00924         checkGLcall("glDisable GL_STENCIL_TEST");
00925     }
00926 }
00927 
00928 static void state_stencilwrite2s(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00929 {
00930     DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
00931     const struct wined3d_gl_info *gl_info = context->gl_info;
00932 
00933     GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK));
00934     checkGLcall("glActiveStencilFaceEXT(GL_BACK)");
00935     glStencilMask(mask);
00936     checkGLcall("glStencilMask");
00937     GL_EXTCALL(glActiveStencilFaceEXT(GL_FRONT));
00938     checkGLcall("glActiveStencilFaceEXT(GL_FRONT)");
00939     glStencilMask(mask);
00940 }
00941 
00942 static void state_stencilwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00943 {
00944     DWORD mask = state->fb->depth_stencil ? state->render_states[WINED3D_RS_STENCILWRITEMASK] : 0;
00945 
00946     glStencilMask(mask);
00947     checkGLcall("glStencilMask");
00948 }
00949 
00950 static void state_fog_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
00951 {
00952 
00953     const struct wined3d_gl_info *gl_info = context->gl_info;
00954     TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
00955 
00956     if (!state->render_states[WINED3D_RS_FOGENABLE])
00957         return;
00958 
00959     /* Table fog on: Never use fog coords, and use per-fragment fog */
00960     if (state->render_states[WINED3D_RS_FOGTABLEMODE] != WINED3D_FOG_NONE)
00961     {
00962         glHint(GL_FOG_HINT, GL_NICEST);
00963         if(context->fog_coord) {
00964             glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
00965             checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
00966             context->fog_coord = FALSE;
00967         }
00968 
00969         /* Range fog is only used with per-vertex fog in d3d */
00970         if (gl_info->supported[NV_FOG_DISTANCE])
00971         {
00972             glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
00973             checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
00974         }
00975         return;
00976     }
00977 
00978     /* Otherwise use per-vertex fog in any case */
00979     glHint(GL_FOG_HINT, GL_FASTEST);
00980 
00981     if (state->render_states[WINED3D_RS_FOGVERTEXMODE] == WINED3D_FOG_NONE || context->last_was_rhw)
00982     {
00983         /* No fog at all, or transformed vertices: Use fog coord */
00984         if(!context->fog_coord) {
00985             glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
00986             checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT)");
00987             context->fog_coord = TRUE;
00988         }
00989     }
00990     else
00991     {
00992         /* Otherwise, use the fragment depth */
00993         if(context->fog_coord) {
00994             glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT);
00995             checkGLcall("glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT)");
00996             context->fog_coord = FALSE;
00997         }
00998 
00999         if (state->render_states[WINED3D_RS_RANGEFOGENABLE])
01000         {
01001             if (gl_info->supported[NV_FOG_DISTANCE])
01002             {
01003                 glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV);
01004                 checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_RADIAL_NV)");
01005             }
01006             else
01007             {
01008                 WARN("Range fog enabled, but not supported by this GL implementation.\n");
01009             }
01010         }
01011         else if (gl_info->supported[NV_FOG_DISTANCE])
01012         {
01013             glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV);
01014             checkGLcall("glFogi(GL_FOG_DISTANCE_MODE_NV, GL_EYE_PLANE_ABSOLUTE_NV)");
01015         }
01016     }
01017 }
01018 
01019 void state_fogstartend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01020 {
01021     float fogstart, fogend;
01022     union {
01023         DWORD d;
01024         float f;
01025     } tmpvalue;
01026 
01027     switch(context->fog_source) {
01028         case FOGSOURCE_VS:
01029             fogstart = 1.0f;
01030             fogend = 0.0f;
01031             break;
01032 
01033         case FOGSOURCE_COORD:
01034             fogstart = 255.0f;
01035             fogend = 0.0f;
01036             break;
01037 
01038         case FOGSOURCE_FFP:
01039             tmpvalue.d = state->render_states[WINED3D_RS_FOGSTART];
01040             fogstart = tmpvalue.f;
01041             tmpvalue.d = state->render_states[WINED3D_RS_FOGEND];
01042             fogend = tmpvalue.f;
01043             /* In GL, fogstart == fogend disables fog, in D3D everything's fogged.*/
01044             if(fogstart == fogend) {
01045                 fogstart = -INFINITY;
01046                 fogend = 0.0f;
01047             }
01048             break;
01049 
01050         default:
01051             /* This should not happen.context->fog_source is set in wined3d, not the app.
01052              * Still this is needed to make the compiler happy
01053              */
01054             ERR("Unexpected fog coordinate source\n");
01055             fogstart = 0.0f;
01056             fogend = 0.0f;
01057     }
01058 
01059     glFogf(GL_FOG_START, fogstart);
01060     checkGLcall("glFogf(GL_FOG_START, fogstart)");
01061     TRACE("Fog Start == %f\n", fogstart);
01062 
01063     glFogf(GL_FOG_END, fogend);
01064     checkGLcall("glFogf(GL_FOG_END, fogend)");
01065     TRACE("Fog End == %f\n", fogend);
01066 }
01067 
01068 void state_fog_fragpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01069 {
01070     enum fogsource new_source;
01071 
01072     TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
01073 
01074     if (!state->render_states[WINED3D_RS_FOGENABLE])
01075     {
01076         /* No fog? Disable it, and we're done :-) */
01077         glDisableWINE(GL_FOG);
01078         checkGLcall("glDisable GL_FOG");
01079         return;
01080     }
01081 
01082     /* Fog Rules:
01083      *
01084      * With fixed function vertex processing, Direct3D knows 2 different fog input sources.
01085      * It can use the Z value of the vertex, or the alpha component of the specular color.
01086      * This depends on the fog vertex, fog table and the vertex declaration. If the Z value
01087      * is used, fogstart, fogend and the equation type are used, otherwise linear fog with
01088      * start = 255, end = 0 is used. Obviously the msdn is not very clear on that.
01089      *
01090      * FOGTABLEMODE != NONE:
01091      *  The Z value is used, with the equation specified, no matter what vertex type.
01092      *
01093      * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, untransformed:
01094      *  Per vertex fog is calculated using the specified fog equation and the parameters
01095      *
01096      * FOGTABLEMODE == NONE, FOGVERTEXMODE != NONE, transformed, OR
01097      * FOGTABLEMODE == NONE, FOGVERTEXMODE == NONE, untransformed:
01098      *  Linear fog with start = 255.0, end = 0.0, input comes from the specular color
01099      *
01100      *
01101      * Rules for vertex fog with shaders:
01102      *
01103      * When mixing fixed function functionality with the programmable pipeline, D3D expects
01104      * the fog computation to happen during transformation while openGL expects it to happen
01105      * during rasterization. Also, prior to pixel shader 3.0 D3D handles fog blending after
01106      * the pixel shader while openGL always expects the pixel shader to handle the blending.
01107      * To solve this problem, WineD3D does:
01108      * 1) implement a linear fog equation and fog blending at the end of every pre 3.0 pixel
01109      * shader,
01110      * and 2) disables the fog computation (in either the fixed function or programmable
01111      * rasterizer) if using a vertex program.
01112      *
01113      * D3D shaders can provide an explicit fog coordinate. This fog coordinate is used with
01114      * D3DRS_FOGTABLEMODE==D3DFOG_NONE. The FOGVERTEXMODE is ignored, d3d always uses linear
01115      * fog with start=1.0 and end=0.0 in this case. This is similar to fog coordinates in
01116      * the specular color, a vertex shader counts as pretransformed geometry in this case.
01117      * There are some GL differences between specular fog coords and vertex shaders though.
01118      *
01119      * With table fog the vertex shader fog coordinate is ignored.
01120      *
01121      * If a fogtablemode and a fogvertexmode are specified, table fog is applied (with or
01122      * without shaders).
01123      */
01124 
01125     /* DX 7 sdk: "If both render states(vertex and table fog) are set to valid modes,
01126      * the system will apply only pixel(=table) fog effects."
01127      */
01128     if (state->render_states[WINED3D_RS_FOGTABLEMODE] == WINED3D_FOG_NONE)
01129     {
01130         if (use_vs(state))
01131         {
01132             glFogi(GL_FOG_MODE, GL_LINEAR);
01133             checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
01134             new_source = FOGSOURCE_VS;
01135         }
01136         else
01137         {
01138             switch (state->render_states[WINED3D_RS_FOGVERTEXMODE])
01139             {
01140                 /* If processed vertices are used, fall through to the NONE case */
01141                 case WINED3D_FOG_EXP:
01142                     if (!context->last_was_rhw)
01143                     {
01144                         glFogi(GL_FOG_MODE, GL_EXP);
01145                         checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
01146                         new_source = FOGSOURCE_FFP;
01147                         break;
01148                     }
01149                     /* drop through */
01150 
01151                 case WINED3D_FOG_EXP2:
01152                     if (!context->last_was_rhw)
01153                     {
01154                         glFogi(GL_FOG_MODE, GL_EXP2);
01155                         checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
01156                         new_source = FOGSOURCE_FFP;
01157                         break;
01158                     }
01159                     /* drop through */
01160 
01161                 case WINED3D_FOG_LINEAR:
01162                     if (!context->last_was_rhw)
01163                     {
01164                         glFogi(GL_FOG_MODE, GL_LINEAR);
01165                         checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
01166                         new_source = FOGSOURCE_FFP;
01167                         break;
01168                     }
01169                     /* drop through */
01170 
01171                 case WINED3D_FOG_NONE:
01172                     /* Both are none? According to msdn the alpha channel of the specular
01173                      * color contains a fog factor. Set it in drawStridedSlow.
01174                      * Same happens with Vertexfog on transformed vertices
01175                      */
01176                     new_source = FOGSOURCE_COORD;
01177                     glFogi(GL_FOG_MODE, GL_LINEAR);
01178                     checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
01179                     break;
01180 
01181                 default:
01182                     FIXME("Unexpected WINED3D_RS_FOGVERTEXMODE %#x.\n",
01183                             state->render_states[WINED3D_RS_FOGVERTEXMODE]);
01184                     new_source = FOGSOURCE_FFP; /* Make the compiler happy */
01185             }
01186         }
01187     } else {
01188         new_source = FOGSOURCE_FFP;
01189 
01190         switch (state->render_states[WINED3D_RS_FOGTABLEMODE])
01191         {
01192             case WINED3D_FOG_EXP:
01193                 glFogi(GL_FOG_MODE, GL_EXP);
01194                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP)");
01195                 break;
01196 
01197             case WINED3D_FOG_EXP2:
01198                 glFogi(GL_FOG_MODE, GL_EXP2);
01199                 checkGLcall("glFogi(GL_FOG_MODE, GL_EXP2)");
01200                 break;
01201 
01202             case WINED3D_FOG_LINEAR:
01203                 glFogi(GL_FOG_MODE, GL_LINEAR);
01204                 checkGLcall("glFogi(GL_FOG_MODE, GL_LINEAR)");
01205                 break;
01206 
01207             case WINED3D_FOG_NONE:   /* Won't happen */
01208             default:
01209                 FIXME("Unexpected WINED3D_RS_FOGTABLEMODE %#x.\n",
01210                         state->render_states[WINED3D_RS_FOGTABLEMODE]);
01211         }
01212     }
01213 
01214     glEnableWINE(GL_FOG);
01215     checkGLcall("glEnable GL_FOG");
01216     if (new_source != context->fog_source)
01217     {
01218         context->fog_source = new_source;
01219         state_fogstartend(context, state, STATE_RENDER(WINED3D_RS_FOGSTART));
01220     }
01221 }
01222 
01223 void state_fogcolor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01224 {
01225     float col[4];
01226 
01227     D3DCOLORTOGLFLOAT4(state->render_states[WINED3D_RS_FOGCOLOR], col);
01228     glFogfv(GL_FOG_COLOR, &col[0]);
01229     checkGLcall("glFog GL_FOG_COLOR");
01230 }
01231 
01232 void state_fogdensity(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01233 {
01234     union {
01235         DWORD d;
01236         float f;
01237     } tmpvalue;
01238 
01239     tmpvalue.d = state->render_states[WINED3D_RS_FOGDENSITY];
01240     glFogfv(GL_FOG_DENSITY, &tmpvalue.f);
01241     checkGLcall("glFogf(GL_FOG_DENSITY, (float) Value)");
01242 }
01243 
01244 static void state_colormat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01245 {
01246     const struct wined3d_device *device = context->swapchain->device;
01247     GLenum Parm = 0;
01248 
01249     /* Depends on the decoded vertex declaration to read the existence of diffuse data.
01250      * The vertex declaration will call this function if the fixed function pipeline is used.
01251      */
01252 
01253     if(isStateDirty(context, STATE_VDECL)) {
01254         return;
01255     }
01256 
01257     context->num_untracked_materials = 0;
01258     if ((device->strided_streams.use_map & (1 << WINED3D_FFP_DIFFUSE))
01259             && state->render_states[WINED3D_RS_COLORVERTEX])
01260     {
01261         TRACE("diff %d, amb %d, emis %d, spec %d\n",
01262                 state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE],
01263                 state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE],
01264                 state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE],
01265                 state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE]);
01266 
01267         if (state->render_states[WINED3D_RS_DIFFUSEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01268         {
01269             if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01270                 Parm = GL_AMBIENT_AND_DIFFUSE;
01271             else
01272                 Parm = GL_DIFFUSE;
01273             if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01274             {
01275                 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
01276                 context->num_untracked_materials++;
01277             }
01278             if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01279             {
01280                 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
01281                 context->num_untracked_materials++;
01282             }
01283         }
01284         else if (state->render_states[WINED3D_RS_AMBIENTMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01285         {
01286             Parm = GL_AMBIENT;
01287             if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01288             {
01289                 context->untracked_materials[context->num_untracked_materials] = GL_EMISSION;
01290                 context->num_untracked_materials++;
01291             }
01292             if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01293             {
01294                 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
01295                 context->num_untracked_materials++;
01296             }
01297         }
01298         else if (state->render_states[WINED3D_RS_EMISSIVEMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01299         {
01300             Parm = GL_EMISSION;
01301             if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01302             {
01303                 context->untracked_materials[context->num_untracked_materials] = GL_SPECULAR;
01304                 context->num_untracked_materials++;
01305             }
01306         }
01307         else if (state->render_states[WINED3D_RS_SPECULARMATERIALSOURCE] == WINED3D_MCS_COLOR1)
01308         {
01309             Parm = GL_SPECULAR;
01310         }
01311     }
01312 
01313     /* Nothing changed, return. */
01314     if (Parm == context->tracking_parm) return;
01315 
01316     if(!Parm) {
01317         glDisable(GL_COLOR_MATERIAL);
01318         checkGLcall("glDisable GL_COLOR_MATERIAL");
01319     } else {
01320         glColorMaterial(GL_FRONT_AND_BACK, Parm);
01321         checkGLcall("glColorMaterial(GL_FRONT_AND_BACK, Parm)");
01322         glEnable(GL_COLOR_MATERIAL);
01323         checkGLcall("glEnable(GL_COLOR_MATERIAL)");
01324     }
01325 
01326     /* Apparently calls to glMaterialfv are ignored for properties we're
01327      * tracking with glColorMaterial, so apply those here. */
01328     switch (context->tracking_parm) {
01329         case GL_AMBIENT_AND_DIFFUSE:
01330             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
01331             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
01332             checkGLcall("glMaterialfv");
01333             break;
01334 
01335         case GL_DIFFUSE:
01336             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float *)&state->material.diffuse);
01337             checkGLcall("glMaterialfv");
01338             break;
01339 
01340         case GL_AMBIENT:
01341             glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float *)&state->material.ambient);
01342             checkGLcall("glMaterialfv");
01343             break;
01344 
01345         case GL_EMISSION:
01346             glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (float *)&state->material.emissive);
01347             checkGLcall("glMaterialfv");
01348             break;
01349 
01350         case GL_SPECULAR:
01351             /* Only change material color if specular is enabled, otherwise it is set to black */
01352             if (state->render_states[WINED3D_RS_SPECULARENABLE])
01353             {
01354                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float *)&state->material.specular);
01355                 checkGLcall("glMaterialfv");
01356             }
01357             else
01358             {
01359                 static const GLfloat black[] = {0.0f, 0.0f, 0.0f, 0.0f};
01360                 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, &black[0]);
01361                 checkGLcall("glMaterialfv");
01362             }
01363             break;
01364     }
01365 
01366     context->tracking_parm = Parm;
01367 }
01368 
01369 static void state_linepattern(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01370 {
01371     union
01372     {
01373         DWORD d;
01374         struct wined3d_line_pattern lp;
01375     } tmppattern;
01376     tmppattern.d = state->render_states[WINED3D_RS_LINEPATTERN];
01377 
01378     TRACE("Line pattern: repeat %d bits %x.\n", tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
01379 
01380     if (tmppattern.lp.repeat_factor)
01381     {
01382         glLineStipple(tmppattern.lp.repeat_factor, tmppattern.lp.line_pattern);
01383         checkGLcall("glLineStipple(repeat, linepattern)");
01384         glEnable(GL_LINE_STIPPLE);
01385         checkGLcall("glEnable(GL_LINE_STIPPLE);");
01386     }
01387     else
01388     {
01389         glDisable(GL_LINE_STIPPLE);
01390         checkGLcall("glDisable(GL_LINE_STIPPLE);");
01391     }
01392 }
01393 
01394 static void state_normalize(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01395 {
01396     if (isStateDirty(context, STATE_VDECL))
01397         return;
01398 
01399     /* Without vertex normals, we set the current normal to 0/0/0 to remove the diffuse factor
01400      * from the opengl lighting equation, as d3d does. Normalization of 0/0/0 can lead to a division
01401      * by zero and is not properly defined in opengl, so avoid it
01402      */
01403     if (state->render_states[WINED3D_RS_NORMALIZENORMALS]
01404             && (context->swapchain->device->strided_streams.use_map & (1 << WINED3D_FFP_NORMAL)))
01405     {
01406         glEnable(GL_NORMALIZE);
01407         checkGLcall("glEnable(GL_NORMALIZE);");
01408     }
01409     else
01410     {
01411         glDisable(GL_NORMALIZE);
01412         checkGLcall("glDisable(GL_NORMALIZE);");
01413     }
01414 }
01415 
01416 static void state_psizemin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01417 {
01418     union {
01419         DWORD d;
01420         float f;
01421     } tmpvalue;
01422 
01423     tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
01424     if (tmpvalue.f != 1.0f)
01425     {
01426         FIXME("WINED3D_RS_POINTSIZE_MIN not supported on this opengl, value is %f\n", tmpvalue.f);
01427     }
01428     tmpvalue.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
01429     if (tmpvalue.f != 64.0f)
01430     {
01431         FIXME("WINED3D_RS_POINTSIZE_MAX not supported on this opengl, value is %f\n", tmpvalue.f);
01432     }
01433 
01434 }
01435 
01436 static void state_psizemin_ext(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01437 {
01438     const struct wined3d_gl_info *gl_info = context->gl_info;
01439     union
01440     {
01441         DWORD d;
01442         float f;
01443     } min, max;
01444 
01445     min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
01446     max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
01447 
01448     /* Max point size trumps min point size */
01449     if(min.f > max.f) {
01450         min.f = max.f;
01451     }
01452 
01453     GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MIN_EXT, min.f);
01454     checkGLcall("glPointParameterfEXT(...)");
01455     GL_EXTCALL(glPointParameterfEXT)(GL_POINT_SIZE_MAX_EXT, max.f);
01456     checkGLcall("glPointParameterfEXT(...)");
01457 }
01458 
01459 static void state_psizemin_arb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01460 {
01461     const struct wined3d_gl_info *gl_info = context->gl_info;
01462     union
01463     {
01464         DWORD d;
01465         float f;
01466     } min, max;
01467 
01468     min.d = state->render_states[WINED3D_RS_POINTSIZE_MIN];
01469     max.d = state->render_states[WINED3D_RS_POINTSIZE_MAX];
01470 
01471     /* Max point size trumps min point size */
01472     if(min.f > max.f) {
01473         min.f = max.f;
01474     }
01475 
01476     GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MIN_ARB, min.f);
01477     checkGLcall("glPointParameterfARB(...)");
01478     GL_EXTCALL(glPointParameterfARB)(GL_POINT_SIZE_MAX_ARB, max.f);
01479     checkGLcall("glPointParameterfARB(...)");
01480 }
01481 
01482 static void state_pscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01483 {
01484     const struct wined3d_gl_info *gl_info = context->gl_info;
01485     /* TODO: Group this with the viewport */
01486     /*
01487      * POINTSCALEENABLE controls how point size value is treated. If set to
01488      * true, the point size is scaled with respect to height of viewport.
01489      * When set to false point size is in pixels.
01490      */
01491 
01492     /* Default values */
01493     GLfloat att[3] = {1.0f, 0.0f, 0.0f};
01494     union {
01495         DWORD d;
01496         float f;
01497     } pointSize, A, B, C;
01498 
01499     pointSize.d = state->render_states[WINED3D_RS_POINTSIZE];
01500     A.d = state->render_states[WINED3D_RS_POINTSCALE_A];
01501     B.d = state->render_states[WINED3D_RS_POINTSCALE_B];
01502     C.d = state->render_states[WINED3D_RS_POINTSCALE_C];
01503 
01504     if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
01505     {
01506         DWORD h = state->viewport.height;
01507         GLfloat scaleFactor;
01508 
01509         if (pointSize.f < gl_info->limits.pointsize_min)
01510         {
01511             /* Minimum valid point size for OpenGL is driver specific. For Direct3D it is
01512              * 0.0f. This means that OpenGL will clamp really small point sizes to the
01513              * driver minimum. To correct for this we need to multiply by the scale factor when sizes
01514              * are less than 1.0f. scale_factor =  1.0f / point_size.
01515              */
01516             scaleFactor = pointSize.f / gl_info->limits.pointsize_min;
01517             /* Clamp the point size, don't rely on the driver to do it. MacOS says min point size
01518              * is 1.0, but then accepts points below that and draws too small points
01519              */
01520             pointSize.f = gl_info->limits.pointsize_min;
01521         }
01522         else if(pointSize.f > gl_info->limits.pointsize_max)
01523         {
01524             /* gl already scales the input to glPointSize,
01525              * d3d scales the result after the point size scale.
01526              * If the point size is bigger than the max size, use the
01527              * scaling to scale it bigger, and set the gl point size to max
01528              */
01529             scaleFactor = pointSize.f / gl_info->limits.pointsize_max;
01530             TRACE("scale: %f\n", scaleFactor);
01531             pointSize.f = gl_info->limits.pointsize_max;
01532         } else {
01533             scaleFactor = 1.0f;
01534         }
01535         scaleFactor = powf(h * scaleFactor, 2);
01536 
01537         att[0] = A.f / scaleFactor;
01538         att[1] = B.f / scaleFactor;
01539         att[2] = C.f / scaleFactor;
01540     }
01541 
01542     if (gl_info->supported[ARB_POINT_PARAMETERS])
01543     {
01544         GL_EXTCALL(glPointParameterfvARB)(GL_POINT_DISTANCE_ATTENUATION_ARB, att);
01545         checkGLcall("glPointParameterfvARB(GL_DISTANCE_ATTENUATION_ARB, ...)");
01546     }
01547     else if (gl_info->supported[EXT_POINT_PARAMETERS])
01548     {
01549         GL_EXTCALL(glPointParameterfvEXT)(GL_DISTANCE_ATTENUATION_EXT, att);
01550         checkGLcall("glPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, ...)");
01551     }
01552     else if (state->render_states[WINED3D_RS_POINTSCALEENABLE])
01553     {
01554         WARN("POINT_PARAMETERS not supported in this version of opengl\n");
01555     }
01556 
01557     glPointSize(pointSize.f);
01558     checkGLcall("glPointSize(...);");
01559 }
01560 
01561 static void state_debug_monitor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01562 {
01563     WARN("token: %#x.\n", state->render_states[WINED3D_RS_DEBUGMONITORTOKEN]);
01564 }
01565 
01566 static void state_colorwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01567 {
01568     DWORD mask0 = state->render_states[WINED3D_RS_COLORWRITEENABLE];
01569     DWORD mask1 = state->render_states[WINED3D_RS_COLORWRITEENABLE1];
01570     DWORD mask2 = state->render_states[WINED3D_RS_COLORWRITEENABLE2];
01571     DWORD mask3 = state->render_states[WINED3D_RS_COLORWRITEENABLE3];
01572 
01573     TRACE("Color mask: r(%d) g(%d) b(%d) a(%d)\n",
01574             mask0 & WINED3DCOLORWRITEENABLE_RED ? 1 : 0,
01575             mask0 & WINED3DCOLORWRITEENABLE_GREEN ? 1 : 0,
01576             mask0 & WINED3DCOLORWRITEENABLE_BLUE ? 1 : 0,
01577             mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? 1 : 0);
01578     glColorMask(mask0 & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
01579             mask0 & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
01580             mask0 & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
01581             mask0 & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE);
01582     checkGLcall("glColorMask(...)");
01583 
01584     if (!((mask1 == mask0 && mask2 == mask0 && mask3 == mask0)
01585         || (mask1 == 0xf && mask2 == 0xf && mask3 == 0xf)))
01586     {
01587         FIXME("WINED3D_RS_COLORWRITEENABLE/1/2/3, %#x/%#x/%#x/%#x not yet implemented.\n",
01588             mask0, mask1, mask2, mask3);
01589         FIXME("Missing of cap D3DPMISCCAPS_INDEPENDENTWRITEMASKS wasn't honored?\n");
01590     }
01591 }
01592 
01593 static void set_color_mask(const struct wined3d_gl_info *gl_info, UINT index, DWORD mask)
01594 {
01595     GL_EXTCALL(glColorMaskIndexedEXT(index,
01596             mask & WINED3DCOLORWRITEENABLE_RED ? GL_TRUE : GL_FALSE,
01597             mask & WINED3DCOLORWRITEENABLE_GREEN ? GL_TRUE : GL_FALSE,
01598             mask & WINED3DCOLORWRITEENABLE_BLUE ? GL_TRUE : GL_FALSE,
01599             mask & WINED3DCOLORWRITEENABLE_ALPHA ? GL_TRUE : GL_FALSE));
01600 }
01601 
01602 static void state_colorwrite0(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01603 {
01604     set_color_mask(context->gl_info, 0, state->render_states[WINED3D_RS_COLORWRITEENABLE]);
01605 }
01606 
01607 static void state_colorwrite1(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01608 {
01609     set_color_mask(context->gl_info, 1, state->render_states[WINED3D_RS_COLORWRITEENABLE1]);
01610 }
01611 
01612 static void state_colorwrite2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01613 {
01614     set_color_mask(context->gl_info, 2, state->render_states[WINED3D_RS_COLORWRITEENABLE2]);
01615 }
01616 
01617 static void state_colorwrite3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01618 {
01619     set_color_mask(context->gl_info, 3, state->render_states[WINED3D_RS_COLORWRITEENABLE3]);
01620 }
01621 
01622 static void state_localviewer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01623 {
01624     if (state->render_states[WINED3D_RS_LOCALVIEWER])
01625     {
01626         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
01627         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1)");
01628     } else {
01629         glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
01630         checkGLcall("glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 0)");
01631     }
01632 }
01633 
01634 static void state_lastpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01635 {
01636     if (state->render_states[WINED3D_RS_LASTPIXEL])
01637     {
01638         TRACE("Last Pixel Drawing Enabled\n");
01639     }
01640     else
01641     {
01642         static BOOL warned;
01643         if (!warned) {
01644             FIXME("Last Pixel Drawing Disabled, not handled yet\n");
01645             warned = TRUE;
01646         } else {
01647             TRACE("Last Pixel Drawing Disabled, not handled yet\n");
01648         }
01649     }
01650 }
01651 
01652 static void state_pointsprite_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01653 {
01654     static BOOL warned;
01655 
01656     /* TODO: NV_POINT_SPRITE */
01657     if (!warned && state->render_states[WINED3D_RS_POINTSPRITEENABLE])
01658     {
01659         /* A FIXME, not a WARN because point sprites should be software emulated if not supported by HW */
01660         FIXME("Point sprites not supported\n");
01661         warned = TRUE;
01662     }
01663 }
01664 
01665 static void state_pointsprite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01666 {
01667     if (state->render_states[WINED3D_RS_POINTSPRITEENABLE])
01668     {
01669         glEnable(GL_POINT_SPRITE_ARB);
01670         checkGLcall("glEnable(GL_POINT_SPRITE_ARB)");
01671     } else {
01672         glDisable(GL_POINT_SPRITE_ARB);
01673         checkGLcall("glDisable(GL_POINT_SPRITE_ARB)");
01674     }
01675 }
01676 
01677 static void state_wrap(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01678 {
01679     if (state->render_states[WINED3D_RS_WRAP0]
01680             || state->render_states[WINED3D_RS_WRAP1]
01681             || state->render_states[WINED3D_RS_WRAP2]
01682             || state->render_states[WINED3D_RS_WRAP3]
01683             || state->render_states[WINED3D_RS_WRAP4]
01684             || state->render_states[WINED3D_RS_WRAP5]
01685             || state->render_states[WINED3D_RS_WRAP6]
01686             || state->render_states[WINED3D_RS_WRAP7]
01687             || state->render_states[WINED3D_RS_WRAP8]
01688             || state->render_states[WINED3D_RS_WRAP9]
01689             || state->render_states[WINED3D_RS_WRAP10]
01690             || state->render_states[WINED3D_RS_WRAP11]
01691             || state->render_states[WINED3D_RS_WRAP12]
01692             || state->render_states[WINED3D_RS_WRAP13]
01693             || state->render_states[WINED3D_RS_WRAP14]
01694             || state->render_states[WINED3D_RS_WRAP15])
01695         FIXME("(WINED3D_RS_WRAP0) Texture wrapping not yet supported.\n");
01696 }
01697 
01698 static void state_msaa_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01699 {
01700     if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
01701         WARN("Multisample antialiasing not supported by GL.\n");
01702 }
01703 
01704 static void state_msaa(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01705 {
01706     if (state->render_states[WINED3D_RS_MULTISAMPLEANTIALIAS])
01707     {
01708         glEnable(GL_MULTISAMPLE_ARB);
01709         checkGLcall("glEnable(GL_MULTISAMPLE_ARB)");
01710     } else {
01711         glDisable(GL_MULTISAMPLE_ARB);
01712         checkGLcall("glDisable(GL_MULTISAMPLE_ARB)");
01713     }
01714 }
01715 
01716 static void state_scissor(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01717 {
01718     if (state->render_states[WINED3D_RS_SCISSORTESTENABLE])
01719     {
01720         glEnable(GL_SCISSOR_TEST);
01721         checkGLcall("glEnable(GL_SCISSOR_TEST)");
01722     } else {
01723         glDisable(GL_SCISSOR_TEST);
01724         checkGLcall("glDisable(GL_SCISSOR_TEST)");
01725     }
01726 }
01727 
01728 /* The Direct3D depth bias is specified in normalized depth coordinates. In
01729  * OpenGL the bias is specified in units of "the smallest value that is
01730  * guaranteed to produce a resolvable offset for a given implementation". To
01731  * convert from D3D to GL we need to divide the D3D depth bias by that value.
01732  * There's no practical way to retrieve that value from a given GL
01733  * implementation, but the D3D application has essentially the same problem,
01734  * which makes a guess of the depth buffer format's highest possible value a
01735  * reasonable guess. Note that SLOPESCALEDEPTHBIAS is a scaling factor for the
01736  * depth slope, and doesn't need to be scaled. */
01737 static void state_depthbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01738 {
01739     if (state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS]
01740             || state->render_states[WINED3D_RS_DEPTHBIAS])
01741     {
01742         const struct wined3d_surface *depth = state->fb->depth_stencil;
01743         float scale;
01744 
01745         union
01746         {
01747             DWORD d;
01748             float f;
01749         } scale_bias, const_bias;
01750 
01751         scale_bias.d = state->render_states[WINED3D_RS_SLOPESCALEDEPTHBIAS];
01752         const_bias.d = state->render_states[WINED3D_RS_DEPTHBIAS];
01753 
01754         glEnable(GL_POLYGON_OFFSET_FILL);
01755         checkGLcall("glEnable(GL_POLYGON_OFFSET_FILL)");
01756 
01757         if (context->swapchain->device->wined3d->flags & WINED3D_LEGACY_DEPTH_BIAS)
01758         {
01759             float bias = -(float)const_bias.d;
01760             glPolygonOffset(bias, bias);
01761             checkGLcall("glPolygonOffset");
01762         }
01763         else
01764         {
01765             if (depth)
01766             {
01767                 const struct wined3d_format *fmt = depth->resource.format;
01768                 scale = powf(2, fmt->depth_size) - 1;
01769                 TRACE("Depth format %s, using depthbias scale of %.8e.\n",
01770                       debug_d3dformat(fmt->id), scale);
01771             }
01772             else
01773             {
01774                 /* The context manager will reapply this state on a depth stencil change */
01775                 TRACE("No depth stencil, using depthbias scale of 0.0.\n");
01776                 scale = 0.0f;
01777             }
01778 
01779             glPolygonOffset(scale_bias.f, const_bias.f * scale);
01780             checkGLcall("glPolygonOffset(...)");
01781         }
01782     }
01783     else
01784     {
01785         glDisable(GL_POLYGON_OFFSET_FILL);
01786         checkGLcall("glDisable(GL_POLYGON_OFFSET_FILL)");
01787     }
01788 }
01789 
01790 static void state_zvisible(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01791 {
01792     if (state->render_states[WINED3D_RS_ZVISIBLE])
01793         FIXME("WINED3D_RS_ZVISIBLE not implemented.\n");
01794 }
01795 
01796 static void state_perspective(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01797 {
01798     if (state->render_states[WINED3D_RS_TEXTUREPERSPECTIVE])
01799     {
01800         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
01801         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)");
01802     } else {
01803         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
01804         checkGLcall("glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST)");
01805     }
01806 }
01807 
01808 static void state_stippledalpha(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01809 {
01810     if (state->render_states[WINED3D_RS_STIPPLEDALPHA])
01811         FIXME("Stippled Alpha not supported yet.\n");
01812 }
01813 
01814 static void state_antialias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01815 {
01816     if (state->render_states[WINED3D_RS_ANTIALIAS])
01817         FIXME("Antialias not supported yet.\n");
01818 }
01819 
01820 static void state_multisampmask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01821 {
01822     if (state->render_states[WINED3D_RS_MULTISAMPLEMASK] != 0xffffffff)
01823         FIXME("WINED3D_RS_MULTISAMPLEMASK %#x not yet implemented.\n",
01824                 state->render_states[WINED3D_RS_MULTISAMPLEMASK]);
01825 }
01826 
01827 static void state_patchedgestyle(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01828 {
01829     if (state->render_states[WINED3D_RS_PATCHEDGESTYLE] != WINED3D_PATCH_EDGE_DISCRETE)
01830         FIXME("WINED3D_RS_PATCHEDGESTYLE %#x not yet implemented.\n",
01831                 state->render_states[WINED3D_RS_PATCHEDGESTYLE]);
01832 }
01833 
01834 static void state_patchsegments(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01835 {
01836     union {
01837         DWORD d;
01838         float f;
01839     } tmpvalue;
01840     tmpvalue.f = 1.0f;
01841 
01842     if (state->render_states[WINED3D_RS_PATCHSEGMENTS] != tmpvalue.d)
01843     {
01844         static BOOL displayed = FALSE;
01845 
01846         tmpvalue.d = state->render_states[WINED3D_RS_PATCHSEGMENTS];
01847         if(!displayed)
01848             FIXME("(WINED3D_RS_PATCHSEGMENTS,%f) not yet implemented\n", tmpvalue.f);
01849 
01850         displayed = TRUE;
01851     }
01852 }
01853 
01854 static void state_positiondegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01855 {
01856     if (state->render_states[WINED3D_RS_POSITIONDEGREE] != WINED3D_DEGREE_CUBIC)
01857         FIXME("WINED3D_RS_POSITIONDEGREE %#x not yet implemented.\n",
01858                 state->render_states[WINED3D_RS_POSITIONDEGREE]);
01859 }
01860 
01861 static void state_normaldegree(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01862 {
01863     if (state->render_states[WINED3D_RS_NORMALDEGREE] != WINED3D_DEGREE_LINEAR)
01864         FIXME("WINED3D_RS_NORMALDEGREE %#x not yet implemented.\n",
01865                 state->render_states[WINED3D_RS_NORMALDEGREE]);
01866 }
01867 
01868 static void state_tessellation(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01869 {
01870     if (state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION])
01871         FIXME("WINED3D_RS_ENABLEADAPTIVETESSELLATION %#x not yet implemented.\n",
01872                 state->render_states[WINED3D_RS_ENABLEADAPTIVETESSELLATION]);
01873 }
01874 
01875 static void state_nvdb(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01876 {
01877     union {
01878         DWORD d;
01879         float f;
01880     } zmin, zmax;
01881 
01882     const struct wined3d_gl_info *gl_info = context->gl_info;
01883 
01884     if (state->render_states[WINED3D_RS_ADAPTIVETESS_X] == WINED3DFMT_NVDB)
01885     {
01886         zmin.d = state->render_states[WINED3D_RS_ADAPTIVETESS_Z];
01887         zmax.d = state->render_states[WINED3D_RS_ADAPTIVETESS_W];
01888 
01889         /* If zmin is larger than zmax INVALID_VALUE error is generated.
01890          * In d3d9 test is not performed in this case*/
01891         if (zmin.f <= zmax.f)
01892         {
01893             glEnable(GL_DEPTH_BOUNDS_TEST_EXT);
01894             checkGLcall("glEnable(GL_DEPTH_BOUNDS_TEST_EXT)");
01895             GL_EXTCALL(glDepthBoundsEXT(zmin.f, zmax.f));
01896             checkGLcall("glDepthBoundsEXT(...)");
01897         }
01898         else {
01899             glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
01900             checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
01901         }
01902     }
01903     else {
01904         glDisable(GL_DEPTH_BOUNDS_TEST_EXT);
01905         checkGLcall("glDisable(GL_DEPTH_BOUNDS_TEST_EXT)");
01906     }
01907 
01908     state_tessellation(context, state, STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION));
01909 }
01910 
01911 static void state_wrapu(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01912 {
01913     if (state->render_states[WINED3D_RS_WRAPU])
01914         FIXME("Render state WINED3D_RS_WRAPU not implemented yet.\n");
01915 }
01916 
01917 static void state_wrapv(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01918 {
01919     if (state->render_states[WINED3D_RS_WRAPV])
01920         FIXME("Render state WINED3D_RS_WRAPV not implemented yet.\n");
01921 }
01922 
01923 static void state_monoenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01924 {
01925     if (state->render_states[WINED3D_RS_MONOENABLE])
01926         FIXME("Render state WINED3D_RS_MONOENABLE not implemented yet.\n");
01927 }
01928 
01929 static void state_rop2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01930 {
01931     if (state->render_states[WINED3D_RS_ROP2])
01932         FIXME("Render state WINED3D_RS_ROP2 not implemented yet.\n");
01933 }
01934 
01935 static void state_planemask(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01936 {
01937     if (state->render_states[WINED3D_RS_PLANEMASK])
01938         FIXME("Render state WINED3D_RS_PLANEMASK not implemented yet.\n");
01939 }
01940 
01941 static void state_subpixel(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01942 {
01943     if (state->render_states[WINED3D_RS_SUBPIXEL])
01944         FIXME("Render state WINED3D_RS_SUBPIXEL not implemented yet.\n");
01945 }
01946 
01947 static void state_subpixelx(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01948 {
01949     if (state->render_states[WINED3D_RS_SUBPIXELX])
01950         FIXME("Render state WINED3D_RS_SUBPIXELX not implemented yet.\n");
01951 }
01952 
01953 static void state_stippleenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01954 {
01955     if (state->render_states[WINED3D_RS_STIPPLEENABLE])
01956         FIXME("Render state WINED3D_RS_STIPPLEENABLE not implemented yet.\n");
01957 }
01958 
01959 static void state_mipmaplodbias(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01960 {
01961     if (state->render_states[WINED3D_RS_MIPMAPLODBIAS])
01962         FIXME("Render state WINED3D_RS_MIPMAPLODBIAS not implemented yet.\n");
01963 }
01964 
01965 static void state_anisotropy(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01966 {
01967     if (state->render_states[WINED3D_RS_ANISOTROPY])
01968         FIXME("Render state WINED3D_RS_ANISOTROPY not implemented yet.\n");
01969 }
01970 
01971 static void state_flushbatch(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01972 {
01973     if (state->render_states[WINED3D_RS_FLUSHBATCH])
01974         FIXME("Render state WINED3D_RS_FLUSHBATCH not implemented yet.\n");
01975 }
01976 
01977 static void state_translucentsi(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01978 {
01979     if (state->render_states[WINED3D_RS_TRANSLUCENTSORTINDEPENDENT])
01980         FIXME("Render state WINED3D_RS_TRANSLUCENTSORTINDEPENDENT not implemented yet.\n");
01981 }
01982 
01983 static void state_extents(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01984 {
01985     if (state->render_states[WINED3D_RS_EXTENTS])
01986         FIXME("Render state WINED3D_RS_EXTENTS not implemented yet.\n");
01987 }
01988 
01989 static void state_ckeyblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01990 {
01991     if (state->render_states[WINED3D_RS_COLORKEYBLENDENABLE])
01992         FIXME("Render state WINED3D_RS_COLORKEYBLENDENABLE not implemented yet.\n");
01993 }
01994 
01995 static void state_swvp(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
01996 {
01997     if (state->render_states[WINED3D_RS_SOFTWAREVERTEXPROCESSING])
01998         FIXME("Software vertex processing not implemented.\n");
01999 }
02000 
02001 static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) {
02002     /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the
02003     * input should be used for all input components. The WINED3DTA_COMPLEMENT
02004     * flag specifies the complement of the input should be used. */
02005     BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE;
02006     BOOL complement = arg & WINED3DTA_COMPLEMENT;
02007 
02008     /* Calculate the operand */
02009     if (complement) {
02010         if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA;
02011         else *operand = GL_ONE_MINUS_SRC_COLOR;
02012     } else {
02013         if (from_alpha) *operand = GL_SRC_ALPHA;
02014         else *operand = GL_SRC_COLOR;
02015     }
02016 
02017     /* Calculate the source */
02018     switch (arg & WINED3DTA_SELECTMASK) {
02019         case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break;
02020         case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break;
02021         case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break;
02022         case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break;
02023         case WINED3DTA_SPECULAR:
02024             /*
02025             * According to the GL_ARB_texture_env_combine specs, SPECULAR is
02026             * 'Secondary color' and isn't supported until base GL supports it
02027             * There is no concept of temp registers as far as I can tell
02028             */
02029             FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n");
02030             *source = GL_TEXTURE;
02031             break;
02032         default:
02033             FIXME("Unrecognized texture arg %#x\n", arg);
02034             *source = GL_TEXTURE;
02035             break;
02036     }
02037 }
02038 
02039 /* Setup the texture operations texture stage states */
02040 static void set_tex_op(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state,
02041         BOOL isAlpha, int Stage, enum wined3d_texture_op op, DWORD arg1, DWORD arg2, DWORD arg3)
02042 {
02043     GLenum src1, src2, src3;
02044     GLenum opr1, opr2, opr3;
02045     GLenum comb_target;
02046     GLenum src0_target, src1_target, src2_target;
02047     GLenum opr0_target, opr1_target, opr2_target;
02048     GLenum scal_target;
02049     GLenum opr=0, invopr, src3_target, opr3_target;
02050     BOOL Handled = FALSE;
02051 
02052     TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3);
02053 
02054     /* This is called by a state handler which has the gl lock held and a context for the thread */
02055 
02056         /* Note: Operations usually involve two ars, src0 and src1 and are operations of
02057     the form (a1 <operation> a2). However, some of the more complex operations
02058     take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added
02059     in a third parameter called a0. Therefore these are operations of the form
02060     a0 <operation> a1 <operation> a2, i.e., the new parameter goes to the front.
02061 
02062     However, below we treat the new (a0) parameter as src2/opr2, so in the actual
02063     functions below, expect their syntax to differ slightly to those listed in the
02064     manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2
02065     This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP                     */
02066 
02067     if (isAlpha)
02068     {
02069         comb_target = GL_COMBINE_ALPHA;
02070         src0_target = GL_SOURCE0_ALPHA;
02071         src1_target = GL_SOURCE1_ALPHA;
02072         src2_target = GL_SOURCE2_ALPHA;
02073         opr0_target = GL_OPERAND0_ALPHA;
02074         opr1_target = GL_OPERAND1_ALPHA;
02075         opr2_target = GL_OPERAND2_ALPHA;
02076         scal_target = GL_ALPHA_SCALE;
02077     }
02078     else
02079     {
02080         comb_target = GL_COMBINE_RGB;
02081         src0_target = GL_SOURCE0_RGB;
02082         src1_target = GL_SOURCE1_RGB;
02083         src2_target = GL_SOURCE2_RGB;
02084         opr0_target = GL_OPERAND0_RGB;
02085         opr1_target = GL_OPERAND1_RGB;
02086         opr2_target = GL_OPERAND2_RGB;
02087         scal_target = GL_RGB_SCALE;
02088     }
02089 
02090         /* If a texture stage references an invalid texture unit the stage just
02091         * passes through the result from the previous stage */
02092     if (is_invalid_op(state, Stage, op, arg1, arg2, arg3))
02093     {
02094         arg1 = WINED3DTA_CURRENT;
02095         op = WINED3D_TOP_SELECT_ARG1;
02096     }
02097 
02098     if (isAlpha && !state->textures[Stage] && arg1 == WINED3DTA_TEXTURE)
02099     {
02100         get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1);
02101     } else {
02102         get_src_and_opr(arg1, isAlpha, &src1, &opr1);
02103     }
02104     get_src_and_opr(arg2, isAlpha, &src2, &opr2);
02105     get_src_and_opr(arg3, isAlpha, &src3, &opr3);
02106 
02107     TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3);
02108 
02109     Handled = TRUE; /* Assume will be handled */
02110 
02111     /* Other texture operations require special extensions: */
02112     if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
02113     {
02114         if (isAlpha) {
02115             opr = GL_SRC_ALPHA;
02116             invopr = GL_ONE_MINUS_SRC_ALPHA;
02117             src3_target = GL_SOURCE3_ALPHA_NV;
02118             opr3_target = GL_OPERAND3_ALPHA_NV;
02119         } else {
02120             opr = GL_SRC_COLOR;
02121             invopr = GL_ONE_MINUS_SRC_COLOR;
02122             src3_target = GL_SOURCE3_RGB_NV;
02123             opr3_target = GL_OPERAND3_RGB_NV;
02124         }
02125         switch (op)
02126         {
02127             case WINED3D_TOP_DISABLE: /* Only for alpha */
02128                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02129                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
02130                 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
02131                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02132                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
02133                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02134                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02135                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02136                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02137                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02138                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
02139                 checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
02140                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
02141                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
02142                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02143                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02144                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
02145                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
02146                 break;
02147                 case WINED3D_TOP_SELECT_ARG1:                                          /* = a1 * 1 + 0 * 0 */
02148                 case WINED3D_TOP_SELECT_ARG2:                                          /* = a2 * 1 + 0 * 0 */
02149                     glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02150                     checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02151                     if (op == WINED3D_TOP_SELECT_ARG1)
02152                     {
02153                         glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02154                         checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02155                         glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02156                         checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02157                     } else {
02158                         glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
02159                         checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
02160                         glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
02161                         checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
02162                     }
02163                     glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02164                     checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02165                     glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02166                     checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02167                     glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
02168                     checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO");
02169                     glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
02170                     checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
02171                     glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02172                     checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02173                     glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
02174                     checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
02175                     break;
02176 
02177             case WINED3D_TOP_MODULATE:
02178                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02179                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
02180                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02181                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02182                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02183                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02184                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02185                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02186                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02187                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02188                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
02189                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02190                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
02191                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02192                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02193                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02194                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
02195                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
02196                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02197                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02198                 break;
02199             case WINED3D_TOP_MODULATE_2X:
02200                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02201                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
02202                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02203                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02204                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02205                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02206                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02207                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02208                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02209                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02210                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
02211                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02212                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
02213                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02214                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02215                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02216                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
02217                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
02218                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
02219                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
02220                 break;
02221             case WINED3D_TOP_MODULATE_4X:
02222                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02223                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */
02224                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02225                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02226                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02227                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02228                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02229                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02230                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02231                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02232                 glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO);
02233                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02234                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
02235                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02236                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02237                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02238                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
02239                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1");
02240                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
02241                 checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
02242                 break;
02243 
02244             case WINED3D_TOP_ADD:
02245                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02246                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02247                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02248                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02249                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02250                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02251                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02252                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02253                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02254                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02255                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02256                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02257                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02258                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02259                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02260                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02261                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
02262                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
02263                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02264                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02265                 break;
02266 
02267             case WINED3D_TOP_ADD_SIGNED:
02268                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
02269                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
02270                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02271                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02272                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02273                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02274                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02275                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02276                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02277                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02278                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02279                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02280                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02281                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02282                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02283                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02284                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
02285                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
02286                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02287                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02288                 break;
02289 
02290             case WINED3D_TOP_ADD_SIGNED_2X:
02291                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
02292                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
02293                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02294                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02295                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02296                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02297                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02298                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02299                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02300                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02301                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02302                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02303                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02304                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02305                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02306                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02307                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
02308                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
02309                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
02310                 checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
02311                 break;
02312 
02313             case WINED3D_TOP_ADD_SMOOTH:
02314                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02315                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02316                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02317                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02318                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02319                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02320                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02321                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02322                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02323                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02324                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02325                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02326                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02327                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02328                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
02329                 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
02330                 switch (opr1) {
02331                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
02332                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
02333                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02334                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
02335                 }
02336                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
02337                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
02338                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02339                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02340                 break;
02341 
02342             case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
02343                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02344                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02345                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02346                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02347                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02348                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02349                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR);
02350                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_PRIMARY_COLOR");
02351                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02352                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02353                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02354                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02355                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02356                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02357                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR);
02358                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_PRIMARY_COLOR");
02359                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
02360                 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
02361                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02362                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02363                 break;
02364             case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
02365                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02366                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02367                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02368                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02369                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02370                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02371                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE);
02372                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE");
02373                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02374                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02375                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02376                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02377                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02378                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02379                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
02380                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
02381                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
02382                 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
02383                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02384                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02385                 break;
02386             case WINED3D_TOP_BLEND_FACTOR_ALPHA:
02387                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02388                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02389                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02390                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02391                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02392                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02393                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_CONSTANT);
02394                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_CONSTANT");
02395                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02396                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02397                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02398                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02399                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02400                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02401                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_CONSTANT);
02402                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_CONSTANT");
02403                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
02404                 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
02405                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02406                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02407                 break;
02408             case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
02409                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02410                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02411                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02412                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02413                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02414                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02415                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02416                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02417                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02418                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02419                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02420                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02421                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02422                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02423                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE);
02424                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE");
02425                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA);
02426                 checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA");
02427                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02428                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02429                 break;
02430             case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
02431                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02432                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");  /* Add = a0*a1 + a2*a3 */
02433                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);        /*   a0 = src1/opr1    */
02434                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02435                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02436                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");    /*   a1 = 1 (see docs) */
02437                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02438                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02439                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02440                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02441                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);        /*   a2 = arg2         */
02442                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02443                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02444                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");     /*  a3 = src1 alpha   */
02445                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
02446                 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
02447                 switch (opr) {
02448                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
02449                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02450                 }
02451                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
02452                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
02453                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02454                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02455                 break;
02456             case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
02457                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02458                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02459                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02460                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02461                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02462                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02463                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02464                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02465                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02466                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02467                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
02468                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
02469                 switch (opr1) {
02470                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
02471                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02472                 }
02473                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
02474                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
02475                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02476                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02477                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
02478                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
02479                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02480                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02481                 break;
02482             case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
02483                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02484                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02485                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02486                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02487                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02488                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02489                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02490                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02491                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02492                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02493                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02494                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02495                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02496                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02497                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src1);
02498                 checkGLcall("GL_TEXTURE_ENV, src3_target, src1");
02499                 switch (opr1) {
02500                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02501                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
02502                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02503                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
02504                 }
02505                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr);
02506                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr");
02507                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02508                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02509                 break;
02510             case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
02511                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02512                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02513                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02514                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02515                 switch (opr1) {
02516                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
02517                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
02518                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02519                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
02520                 }
02521                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
02522                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
02523                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02524                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02525                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02526                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02527                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
02528                 checkGLcall("GL_TEXTURE_ENV, src2_target, src1");
02529                 switch (opr1) {
02530                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
02531                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02532                 }
02533                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr);
02534                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr");
02535                 glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO);
02536                 checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO");
02537                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr);
02538                 checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr");
02539                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02540                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02541                 break;
02542             case WINED3D_TOP_MULTIPLY_ADD:
02543                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02544                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02545                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src3);
02546                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02547                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3);
02548                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02549                 glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO);
02550                 checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO");
02551                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr);
02552                 checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr");
02553                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src1);
02554                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02555                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1);
02556                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02557                 glTexEnvi(GL_TEXTURE_ENV, src3_target, src2);
02558                 checkGLcall("GL_TEXTURE_ENV, src3_target, src3");
02559                 glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2);
02560                 checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3");
02561                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02562                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02563                 break;
02564 
02565             case WINED3D_TOP_BUMPENVMAP:
02566             case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
02567                 FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n");
02568 
02569             default:
02570                 Handled = FALSE;
02571         }
02572         if (Handled) {
02573             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
02574             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV");
02575 
02576             return;
02577         }
02578     } /* GL_NV_texture_env_combine4 */
02579 
02580     Handled = TRUE; /* Again, assume handled */
02581     switch (op) {
02582         case WINED3D_TOP_DISABLE: /* Only for alpha */
02583             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
02584             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
02585             glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT);
02586             checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT");
02587             glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA);
02588             checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA");
02589             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02590             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02591             break;
02592         case WINED3D_TOP_SELECT_ARG1:
02593             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
02594             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
02595             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02596             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02597             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02598             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02599             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02600             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02601             break;
02602         case WINED3D_TOP_SELECT_ARG2:
02603             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE);
02604             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE");
02605             glTexEnvi(GL_TEXTURE_ENV, src0_target, src2);
02606             checkGLcall("GL_TEXTURE_ENV, src0_target, src2");
02607             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2);
02608             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2");
02609             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02610             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02611             break;
02612         case WINED3D_TOP_MODULATE:
02613             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
02614             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
02615             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02616             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02617             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02618             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02619             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02620             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02621             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02622             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02623             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02624             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02625             break;
02626         case WINED3D_TOP_MODULATE_2X:
02627             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
02628             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
02629             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02630             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02631             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02632             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02633             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02634             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02635             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02636             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02637             glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
02638             checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
02639             break;
02640         case WINED3D_TOP_MODULATE_4X:
02641             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE);
02642             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE");
02643             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02644             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02645             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02646             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02647             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02648             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02649             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02650             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02651             glTexEnvi(GL_TEXTURE_ENV, scal_target, 4);
02652             checkGLcall("GL_TEXTURE_ENV, scal_target, 4");
02653             break;
02654         case WINED3D_TOP_ADD:
02655             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD);
02656             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD");
02657             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02658             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02659             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02660             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02661             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02662             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02663             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02664             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02665             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02666             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02667             break;
02668         case WINED3D_TOP_ADD_SIGNED:
02669             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
02670             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
02671             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02672             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02673             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02674             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02675             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02676             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02677             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02678             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02679             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02680             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02681             break;
02682         case WINED3D_TOP_ADD_SIGNED_2X:
02683             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED);
02684             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD_SIGNED");
02685             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02686             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02687             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02688             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02689             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02690             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02691             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02692             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02693             glTexEnvi(GL_TEXTURE_ENV, scal_target, 2);
02694             checkGLcall("GL_TEXTURE_ENV, scal_target, 2");
02695             break;
02696         case WINED3D_TOP_SUBTRACT:
02697             if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE])
02698             {
02699                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT);
02700                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_SUBTRACT");
02701                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02702                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02703                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02704                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02705                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02706                 checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02707                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02708                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02709                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02710                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02711             } else {
02712                 FIXME("This version of opengl does not support GL_SUBTRACT\n");
02713             }
02714             break;
02715 
02716         case WINED3D_TOP_BLEND_DIFFUSE_ALPHA:
02717             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
02718             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
02719             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02720             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02721             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02722             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02723             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02724             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02725             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02726             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02727             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR);
02728             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR");
02729             glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
02730             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
02731             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02732             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02733             break;
02734         case WINED3D_TOP_BLEND_TEXTURE_ALPHA:
02735             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
02736             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
02737             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02738             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02739             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02740             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02741             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02742             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02743             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02744             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02745             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE);
02746             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE");
02747             glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
02748             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
02749             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02750             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02751             break;
02752         case WINED3D_TOP_BLEND_FACTOR_ALPHA:
02753             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
02754             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
02755             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02756             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02757             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02758             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02759             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02760             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02761             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02762             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02763             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_CONSTANT);
02764             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT");
02765             glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
02766             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
02767             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02768             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02769             break;
02770         case WINED3D_TOP_BLEND_CURRENT_ALPHA:
02771             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
02772             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
02773             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02774             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02775             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02776             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02777             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02778             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02779             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02780             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02781             glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_PREVIOUS);
02782             checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS");
02783             glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA);
02784             checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA");
02785             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02786             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02787             break;
02788         case WINED3D_TOP_DOTPRODUCT3:
02789             if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
02790             {
02791                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB);
02792                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB");
02793             }
02794             else if (gl_info->supported[EXT_TEXTURE_ENV_DOT3])
02795             {
02796                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT);
02797                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT");
02798             } else {
02799                 FIXME("This version of opengl does not support GL_DOT3\n");
02800             }
02801             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02802             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02803             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02804             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02805             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02806             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02807             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02808             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02809             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02810             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02811             break;
02812         case WINED3D_TOP_LERP:
02813             glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE);
02814             checkGLcall("GL_TEXTURE_ENV, comb_target, GL_INTERPOLATE");
02815             glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02816             checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02817             glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02818             checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02819             glTexEnvi(GL_TEXTURE_ENV, src1_target, src2);
02820             checkGLcall("GL_TEXTURE_ENV, src1_target, src2");
02821             glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2);
02822             checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2");
02823             glTexEnvi(GL_TEXTURE_ENV, src2_target, src3);
02824             checkGLcall("GL_TEXTURE_ENV, src2_target, src3");
02825             glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3);
02826             checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3");
02827             glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02828             checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02829             break;
02830         case WINED3D_TOP_ADD_SMOOTH:
02831             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
02832             {
02833                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
02834                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
02835                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02836                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02837                 switch (opr1) {
02838                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
02839                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
02840                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02841                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
02842                 }
02843                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
02844                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
02845                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
02846                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
02847                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
02848                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
02849                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02850                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02851                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02852                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02853                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02854                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02855             } else
02856                 Handled = FALSE;
02857                 break;
02858         case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
02859             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
02860             {
02861                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
02862                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
02863                 glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE);
02864                 checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE");
02865                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA);
02866                 checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA");
02867                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
02868                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
02869                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
02870                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
02871                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02872                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02873                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02874                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02875                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02876                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02877             } else
02878                 Handled = FALSE;
02879                 break;
02880         case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
02881             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
02882             {
02883                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
02884                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
02885                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02886                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02887                 switch (opr1) {
02888                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
02889                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02890                     case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
02891                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02892                 }
02893                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
02894                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
02895                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
02896                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
02897                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
02898                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
02899                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02900                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02901                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02902                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02903                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02904                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02905             } else
02906                 Handled = FALSE;
02907                 break;
02908         case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
02909             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
02910             {
02911                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
02912                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
02913                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02914                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02915                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
02916                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
02917                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
02918                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
02919                 switch (opr1) {
02920                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
02921                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02922                     case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
02923                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02924                 }
02925                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
02926                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
02927                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02928                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02929                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02930                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02931                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02932                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02933             } else
02934                 Handled = FALSE;
02935                 break;
02936         case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
02937             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
02938             {
02939                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
02940                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
02941                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02942                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02943                 switch (opr1) {
02944                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02945                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break;
02946                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02947                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
02948                 }
02949                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
02950                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
02951                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
02952                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
02953                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1);
02954                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1");
02955                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02956                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02957                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02958                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02959                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02960                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02961             } else
02962                 Handled = FALSE;
02963                 break;
02964         case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
02965             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
02966             {
02967                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
02968                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
02969                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
02970                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
02971                 switch (opr1) {
02972                     case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break;
02973                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break;
02974                     case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02975                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
02976                 }
02977                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr);
02978                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr");
02979                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src1);
02980                 checkGLcall("GL_TEXTURE_ENV, src1_target, src1");
02981                 switch (opr1) {
02982                     case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break;
02983                     case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02984                     case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break;
02985                     case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break;
02986                 }
02987                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr);
02988                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr");
02989                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
02990                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
02991                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
02992                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
02993                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
02994                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
02995             } else
02996                 Handled = FALSE;
02997                 break;
02998         case WINED3D_TOP_MULTIPLY_ADD:
02999             if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3])
03000             {
03001                 glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI);
03002                 checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI");
03003                 glTexEnvi(GL_TEXTURE_ENV, src0_target, src1);
03004                 checkGLcall("GL_TEXTURE_ENV, src0_target, src1");
03005                 glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1);
03006                 checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1");
03007                 glTexEnvi(GL_TEXTURE_ENV, src1_target, src3);
03008                 checkGLcall("GL_TEXTURE_ENV, src1_target, src3");
03009                 glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3);
03010                 checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3");
03011                 glTexEnvi(GL_TEXTURE_ENV, src2_target, src2);
03012                 checkGLcall("GL_TEXTURE_ENV, src2_target, src2");
03013                 glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2);
03014                 checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2");
03015                 glTexEnvi(GL_TEXTURE_ENV, scal_target, 1);
03016                 checkGLcall("GL_TEXTURE_ENV, scal_target, 1");
03017             } else
03018                 Handled = FALSE;
03019                 break;
03020         case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
03021         case WINED3D_TOP_BUMPENVMAP:
03022             if (gl_info->supported[NV_TEXTURE_SHADER2])
03023             {
03024                 /* Technically texture shader support without register combiners is possible, but not expected to occur
03025                  * on real world cards, so for now a fixme should be enough
03026                  */
03027                 FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n");
03028             }
03029         default:
03030             Handled = FALSE;
03031     }
03032 
03033     if (Handled) {
03034         BOOL  combineOK = TRUE;
03035         if (gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
03036         {
03037             DWORD op2;
03038 
03039             if (isAlpha)
03040                 op2 = state->texture_states[Stage][WINED3D_TSS_COLOR_OP];
03041             else
03042                 op2 = state->texture_states[Stage][WINED3D_TSS_ALPHA_OP];
03043 
03044             /* Note: If COMBINE4 in effect can't go back to combine! */
03045             switch (op2)
03046             {
03047                 case WINED3D_TOP_ADD_SMOOTH:
03048                 case WINED3D_TOP_BLEND_TEXTURE_ALPHA_PM:
03049                 case WINED3D_TOP_MODULATE_ALPHA_ADD_COLOR:
03050                 case WINED3D_TOP_MODULATE_COLOR_ADD_ALPHA:
03051                 case WINED3D_TOP_MODULATE_INVALPHA_ADD_COLOR:
03052                 case WINED3D_TOP_MODULATE_INVCOLOR_ADD_ALPHA:
03053                 case WINED3D_TOP_MULTIPLY_ADD:
03054                     /* Ignore those implemented in both cases */
03055                     switch (op)
03056                     {
03057                         case WINED3D_TOP_SELECT_ARG1:
03058                         case WINED3D_TOP_SELECT_ARG2:
03059                             combineOK = FALSE;
03060                             Handled   = FALSE;
03061                             break;
03062                         default:
03063                             FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha);
03064                             return;
03065                     }
03066             }
03067         }
03068 
03069         if (combineOK)
03070         {
03071             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
03072             checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE");
03073 
03074             return;
03075         }
03076     }
03077 
03078     /* After all the extensions, if still unhandled, report fixme */
03079     FIXME("Unhandled texture operation %s\n", debug_d3dtop(op));
03080 }
03081 
03082 
03083 static void tex_colorop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03084 {
03085     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
03086     const struct wined3d_device *device = context->swapchain->device;
03087     BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
03088     DWORD mapped_stage = device->texUnitMap[stage];
03089     const struct wined3d_gl_info *gl_info = context->gl_info;
03090 
03091     TRACE("Setting color op for stage %d\n", stage);
03092 
03093     /* Using a pixel shader? Don't care for anything here, the shader applying does it */
03094     if (use_ps(state)) return;
03095 
03096     if (stage != mapped_stage) WARN("Using non 1:1 mapping: %d -> %d!\n", stage, mapped_stage);
03097 
03098     if (mapped_stage != WINED3D_UNMAPPED_STAGE)
03099     {
03100         if (tex_used && mapped_stage >= gl_info->limits.textures)
03101         {
03102             FIXME("Attempt to enable unsupported stage!\n");
03103             return;
03104         }
03105         context_active_texture(context, gl_info, mapped_stage);
03106     }
03107 
03108     if (stage >= state->lowest_disabled_stage)
03109     {
03110         TRACE("Stage disabled\n");
03111         if (mapped_stage != WINED3D_UNMAPPED_STAGE)
03112         {
03113             /* Disable everything here */
03114             glDisable(GL_TEXTURE_2D);
03115             checkGLcall("glDisable(GL_TEXTURE_2D)");
03116             glDisable(GL_TEXTURE_3D);
03117             checkGLcall("glDisable(GL_TEXTURE_3D)");
03118             if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
03119             {
03120                 glDisable(GL_TEXTURE_CUBE_MAP_ARB);
03121                 checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
03122             }
03123             if (gl_info->supported[ARB_TEXTURE_RECTANGLE])
03124             {
03125                 glDisable(GL_TEXTURE_RECTANGLE_ARB);
03126                 checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
03127             }
03128         }
03129         /* All done */
03130         return;
03131     }
03132 
03133     /* The sampler will also activate the correct texture dimensions, so no
03134      * need to do it here if the sampler for this stage is dirty. */
03135     if (!isStateDirty(context, STATE_SAMPLER(stage)) && tex_used)
03136         texture_activate_dimensions(state->textures[stage], gl_info);
03137 
03138     set_tex_op(gl_info, state, FALSE, stage,
03139             state->texture_states[stage][WINED3D_TSS_COLOR_OP],
03140             state->texture_states[stage][WINED3D_TSS_COLOR_ARG1],
03141             state->texture_states[stage][WINED3D_TSS_COLOR_ARG2],
03142             state->texture_states[stage][WINED3D_TSS_COLOR_ARG0]);
03143 }
03144 
03145 void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03146 {
03147     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
03148     const struct wined3d_device *device = context->swapchain->device;
03149     BOOL tex_used = device->fixed_function_usage_map & (1 << stage);
03150     DWORD mapped_stage = device->texUnitMap[stage];
03151     const struct wined3d_gl_info *gl_info = context->gl_info;
03152     DWORD op, arg1, arg2, arg0;
03153 
03154     TRACE("Setting alpha op for stage %d\n", stage);
03155     /* Do not care for enabled / disabled stages, just assign the settings. colorop disables / enables required stuff */
03156     if (mapped_stage != WINED3D_UNMAPPED_STAGE)
03157     {
03158         if (tex_used && mapped_stage >= gl_info->limits.textures)
03159         {
03160             FIXME("Attempt to enable unsupported stage!\n");
03161             return;
03162         }
03163         context_active_texture(context, gl_info, mapped_stage);
03164     }
03165 
03166     op = state->texture_states[stage][WINED3D_TSS_ALPHA_OP];
03167     arg1 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG1];
03168     arg2 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG2];
03169     arg0 = state->texture_states[stage][WINED3D_TSS_ALPHA_ARG0];
03170 
03171     if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !stage && state->textures[0])
03172     {
03173         struct wined3d_texture *texture = state->textures[0];
03174         GLenum texture_dimensions = texture->target;
03175 
03176         if (texture_dimensions == GL_TEXTURE_2D || texture_dimensions == GL_TEXTURE_RECTANGLE_ARB)
03177         {
03178             struct wined3d_surface *surf = surface_from_resource(texture->sub_resources[0]);
03179 
03180             if (surf->CKeyFlags & WINEDDSD_CKSRCBLT && !surf->resource.format->alpha_mask)
03181             {
03182                 /* Color keying needs to pass alpha values from the texture through to have the alpha test work
03183                  * properly. On the other hand applications can still use texture combiners apparently. This code
03184                  * takes care that apps cannot remove the texture's alpha channel entirely.
03185                  *
03186                  * The fixup is required for Prince of Persia 3D(prison bars), while Moto racer 2 requires
03187                  * D3DTOP_MODULATE to work on color keyed surfaces. Aliens vs Predator 1 uses color keyed textures
03188                  * and alpha component of diffuse color to draw things like translucent text and perform other
03189                  * blending effects.
03190                  *
03191                  * Aliens vs Predator 1 relies on diffuse alpha having an effect, so it cannot be ignored. To
03192                  * provide the behavior expected by the game, while emulating the colorkey, diffuse alpha must be
03193                  * modulated with texture alpha. OTOH, Moto racer 2 at some points sets alphaop/alphaarg to
03194                  * SELECTARG/CURRENT, yet puts garbage in diffuse alpha (zeroes). This works on native, because the
03195                  * game disables alpha test and alpha blending. Alpha test is overwritten by wine's for purposes of
03196                  * color-keying though, so this will lead to missing geometry if texture alpha is modulated (pixels
03197                  * fail alpha test). To get around this, ALPHABLENDENABLE state is checked: if the app enables alpha
03198                  * blending, it can be expected to provide meaningful values in diffuse alpha, so it should be
03199                  * modulated with texture alpha; otherwise, selecting diffuse alpha is ignored in favour of texture
03200                  * alpha.
03201                  *
03202                  * What to do with multitexturing? So far no app has been found that uses color keying with
03203                  * multitexturing */
03204                 if (op == WINED3D_TOP_DISABLE)
03205                 {
03206                     arg1 = WINED3DTA_TEXTURE;
03207                     op = WINED3D_TOP_SELECT_ARG1;
03208                 }
03209                 else if (op == WINED3D_TOP_SELECT_ARG1 && arg1 != WINED3DTA_TEXTURE)
03210                 {
03211                     if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
03212                     {
03213                         arg2 = WINED3DTA_TEXTURE;
03214                         op = WINED3D_TOP_MODULATE;
03215                     }
03216                     else arg1 = WINED3DTA_TEXTURE;
03217                 }
03218                 else if (op == WINED3D_TOP_SELECT_ARG2 && arg2 != WINED3DTA_TEXTURE)
03219                 {
03220                     if (state->render_states[WINED3D_RS_ALPHABLENDENABLE])
03221                     {
03222                         arg1 = WINED3DTA_TEXTURE;
03223                         op = WINED3D_TOP_MODULATE;
03224                     }
03225                     else arg2 = WINED3DTA_TEXTURE;
03226                 }
03227             }
03228         }
03229     }
03230 
03231     /* tex_alphaop is shared between the ffp and nvrc because the difference only comes down to
03232      * this if block here, and the other code(color keying, texture unit selection) are the same
03233      */
03234     TRACE("Setting alpha op for stage %d\n", stage);
03235     if (gl_info->supported[NV_REGISTER_COMBINERS])
03236     {
03237         set_tex_op_nvrc(gl_info, state, TRUE, stage, op, arg1, arg2, arg0,
03238                 mapped_stage, state->texture_states[stage][WINED3D_TSS_RESULT_ARG]);
03239     }
03240     else
03241     {
03242         set_tex_op(gl_info, state, TRUE, stage, op, arg1, arg2, arg0);
03243     }
03244 }
03245 
03246 static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03247 {
03248     DWORD texUnit = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
03249     const struct wined3d_device *device = context->swapchain->device;
03250     const struct wined3d_gl_info *gl_info = context->gl_info;
03251     DWORD mapped_stage = device->texUnitMap[texUnit];
03252     BOOL generated;
03253     int coordIdx;
03254 
03255     /* Ignore this when a vertex shader is used, or if the streams aren't sorted out yet */
03256     if (use_vs(state) || isStateDirty(context, STATE_VDECL))
03257     {
03258         TRACE("Using a vertex shader, or stream sources not sorted out yet, skipping\n");
03259         return;
03260     }
03261 
03262     if (mapped_stage == WINED3D_UNMAPPED_STAGE) return;
03263     if (mapped_stage >= gl_info->limits.textures) return;
03264 
03265     context_active_texture(context, gl_info, mapped_stage);
03266     generated = (state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU;
03267     coordIdx = min(state->texture_states[texUnit][WINED3D_TSS_TEXCOORD_INDEX & 0x0000ffff], MAX_TEXTURES - 1);
03268 
03269     set_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + texUnit].u.m[0][0],
03270             state->texture_states[texUnit][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS],
03271             generated, context->last_was_rhw,
03272             device->strided_streams.use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))
03273             ? device->strided_streams.elements[WINED3D_FFP_TEXCOORD0 + coordIdx].format->id
03274             : WINED3DFMT_UNKNOWN,
03275             device->frag_pipe->ffp_proj_control);
03276 
03277     /* The sampler applying function calls us if this changes */
03278     if ((context->lastWasPow2Texture & (1 << texUnit)) && state->textures[texUnit])
03279     {
03280         if(generated) {
03281             FIXME("Non-power2 texture being used with generated texture coords\n");
03282         }
03283         /* NP2 texcoord fixup is implemented for pixelshaders so only enable the
03284            fixed-function-pipeline fixup via pow2Matrix when no PS is used. */
03285         if (!use_ps(state))
03286         {
03287             TRACE("Non power two matrix multiply fixup\n");
03288             glMultMatrixf(state->textures[texUnit]->pow2_matrix);
03289         }
03290     }
03291 }
03292 
03293 static void unload_tex_coords(const struct wined3d_gl_info *gl_info)
03294 {
03295     unsigned int texture_idx;
03296 
03297     for (texture_idx = 0; texture_idx < gl_info->limits.texture_coords; ++texture_idx)
03298     {
03299         GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + texture_idx));
03300         glDisableClientState(GL_TEXTURE_COORD_ARRAY);
03301     }
03302 }
03303 
03304 static void load_tex_coords(const struct wined3d_context *context, const struct wined3d_stream_info *si,
03305         GLuint *curVBO, const struct wined3d_state *state)
03306 {
03307     const struct wined3d_device *device = context->swapchain->device;
03308     const struct wined3d_gl_info *gl_info = context->gl_info;
03309     unsigned int mapped_stage = 0;
03310     unsigned int textureNo = 0;
03311 
03312     for (textureNo = 0; textureNo < gl_info->limits.texture_stages; ++textureNo)
03313     {
03314         int coordIdx = state->texture_states[textureNo][WINED3D_TSS_TEXCOORD_INDEX];
03315 
03316         mapped_stage = device->texUnitMap[textureNo];
03317         if (mapped_stage == WINED3D_UNMAPPED_STAGE) continue;
03318 
03319         if (mapped_stage >= gl_info->limits.texture_coords)
03320         {
03321             FIXME("Attempted to load unsupported texture coordinate %u\n", mapped_stage);
03322             continue;
03323         }
03324 
03325         if (coordIdx < MAX_TEXTURES && (si->use_map & (1 << (WINED3D_FFP_TEXCOORD0 + coordIdx))))
03326         {
03327             const struct wined3d_stream_info_element *e = &si->elements[WINED3D_FFP_TEXCOORD0 + coordIdx];
03328 
03329             TRACE("Setting up texture %u, idx %d, coordindx %u, data {%#x:%p}.\n",
03330                     textureNo, mapped_stage, coordIdx, e->data.buffer_object, e->data.addr);
03331 
03332             if (*curVBO != e->data.buffer_object)
03333             {
03334                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
03335                 checkGLcall("glBindBufferARB");
03336                 *curVBO = e->data.buffer_object;
03337             }
03338 
03339             GL_EXTCALL(glClientActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
03340             checkGLcall("glClientActiveTextureARB");
03341 
03342             /* The coords to supply depend completely on the fvf / vertex shader */
03343             glTexCoordPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
03344                     e->data.addr + state->load_base_vertex_index * e->stride);
03345             glEnableClientState(GL_TEXTURE_COORD_ARRAY);
03346         }
03347         else
03348         {
03349             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + mapped_stage, 0, 0, 0, 1));
03350         }
03351     }
03352     if (gl_info->supported[NV_REGISTER_COMBINERS])
03353     {
03354         /* The number of the mapped stages increases monotonically, so it's fine to use the last used one. */
03355         for (textureNo = mapped_stage + 1; textureNo < gl_info->limits.textures; ++textureNo)
03356         {
03357             GL_EXTCALL(glMultiTexCoord4fARB(GL_TEXTURE0_ARB + textureNo, 0, 0, 0, 1));
03358         }
03359     }
03360 
03361     checkGLcall("loadTexCoords");
03362 }
03363 
03364 static void tex_coordindex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03365 {
03366     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
03367     const struct wined3d_device *device = context->swapchain->device;
03368     static const GLfloat s_plane[] = { 1.0f, 0.0f, 0.0f, 0.0f };
03369     static const GLfloat t_plane[] = { 0.0f, 1.0f, 0.0f, 0.0f };
03370     static const GLfloat r_plane[] = { 0.0f, 0.0f, 1.0f, 0.0f };
03371     static const GLfloat q_plane[] = { 0.0f, 0.0f, 0.0f, 1.0f };
03372     const struct wined3d_gl_info *gl_info = context->gl_info;
03373     DWORD mapped_stage = device->texUnitMap[stage];
03374 
03375     if (mapped_stage == WINED3D_UNMAPPED_STAGE)
03376     {
03377         TRACE("No texture unit mapped to stage %d. Skipping texture coordinates.\n", stage);
03378         return;
03379     }
03380 
03381     if (mapped_stage >= gl_info->limits.fragment_samplers)
03382     {
03383         WARN("stage %u not mapped to a valid texture unit (%u)\n", stage, mapped_stage);
03384         return;
03385     }
03386     context_active_texture(context, gl_info, mapped_stage);
03387 
03388     /* Values 0-7 are indexes into the FVF tex coords - See comments in DrawPrimitive
03389      *
03390      * FIXME: When using generated texture coordinates, the index value is used to specify the wrapping mode.
03391      * eg. SetTextureStageState( 0, WINED3D_TSS_TEXCOORDINDEX, WINED3D_TSS_TCI_CAMERASPACEPOSITION | 1 );
03392      * means use the vertex position (camera-space) as the input texture coordinates
03393      * for this texture stage, and the wrap mode set in the WINED3D_RS_WRAP1 render
03394      * state. We do not (yet) support the WINED3DRENDERSTATE_WRAPx values, nor tie them up
03395      * to the TEXCOORDINDEX value
03396      */
03397     switch (state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000)
03398     {
03399         case WINED3DTSS_TCI_PASSTHRU:
03400             /* Use the specified texture coordinates contained within the
03401              * vertex format. This value resolves to zero. */
03402             glDisable(GL_TEXTURE_GEN_S);
03403             glDisable(GL_TEXTURE_GEN_T);
03404             glDisable(GL_TEXTURE_GEN_R);
03405             glDisable(GL_TEXTURE_GEN_Q);
03406             checkGLcall("WINED3DTSS_TCI_PASSTHRU - Disable texgen.");
03407             break;
03408 
03409         case WINED3DTSS_TCI_CAMERASPACEPOSITION:
03410             /* CameraSpacePosition means use the vertex position, transformed to camera space,
03411              * as the input texture coordinates for this stage's texture transformation. This
03412              * equates roughly to EYE_LINEAR */
03413 
03414             glMatrixMode(GL_MODELVIEW);
03415             glPushMatrix();
03416             glLoadIdentity();
03417             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
03418             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
03419             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
03420             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
03421             glPopMatrix();
03422             checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set eye plane.");
03423 
03424             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
03425             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
03426             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
03427             checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Set texgen mode.");
03428 
03429             glEnable(GL_TEXTURE_GEN_S);
03430             glEnable(GL_TEXTURE_GEN_T);
03431             glEnable(GL_TEXTURE_GEN_R);
03432             checkGLcall("WINED3DTSS_TCI_CAMERASPACEPOSITION - Enable texgen.");
03433 
03434             break;
03435 
03436         case WINED3DTSS_TCI_CAMERASPACENORMAL:
03437             /* Note that NV_TEXGEN_REFLECTION support is implied when
03438              * ARB_TEXTURE_CUBE_MAP is supported */
03439             if (!gl_info->supported[NV_TEXGEN_REFLECTION])
03440             {
03441                 FIXME("WINED3DTSS_TCI_CAMERASPACENORMAL not supported.\n");
03442                 break;
03443             }
03444 
03445             glMatrixMode(GL_MODELVIEW);
03446             glPushMatrix();
03447             glLoadIdentity();
03448             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
03449             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
03450             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
03451             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
03452             glPopMatrix();
03453             checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set eye plane.");
03454 
03455             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
03456             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
03457             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_NV);
03458             checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Set texgen mode.");
03459 
03460             glEnable(GL_TEXTURE_GEN_S);
03461             glEnable(GL_TEXTURE_GEN_T);
03462             glEnable(GL_TEXTURE_GEN_R);
03463             checkGLcall("WINED3DTSS_TCI_CAMERASPACENORMAL - Enable texgen.");
03464 
03465             break;
03466 
03467         case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR:
03468             /* Note that NV_TEXGEN_REFLECTION support is implied when
03469              * ARB_TEXTURE_CUBE_MAP is supported */
03470             if (!gl_info->supported[NV_TEXGEN_REFLECTION])
03471             {
03472                 FIXME("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR not supported.\n");
03473                 break;
03474             }
03475 
03476             glMatrixMode(GL_MODELVIEW);
03477             glPushMatrix();
03478             glLoadIdentity();
03479             glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
03480             glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
03481             glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);
03482             glTexGenfv(GL_Q, GL_EYE_PLANE, q_plane);
03483             glPopMatrix();
03484             checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set eye plane.");
03485 
03486             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
03487             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
03488             glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_NV);
03489             checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Set texgen mode.");
03490 
03491             glEnable(GL_TEXTURE_GEN_S);
03492             glEnable(GL_TEXTURE_GEN_T);
03493             glEnable(GL_TEXTURE_GEN_R);
03494             checkGLcall("WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR - Enable texgen.");
03495 
03496             break;
03497 
03498         case WINED3DTSS_TCI_SPHEREMAP:
03499             glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
03500             glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
03501             checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Set texgen mode.");
03502 
03503             glEnable(GL_TEXTURE_GEN_S);
03504             glEnable(GL_TEXTURE_GEN_T);
03505             glDisable(GL_TEXTURE_GEN_R);
03506             checkGLcall("WINED3DTSS_TCI_SPHEREMAP - Enable texgen.");
03507 
03508             break;
03509 
03510         default:
03511             FIXME("Unhandled WINED3D_TSS_TEXCOORD_INDEX %#x.\n",
03512                     state->texture_states[stage][WINED3D_TSS_TEXCOORD_INDEX]);
03513             glDisable(GL_TEXTURE_GEN_S);
03514             glDisable(GL_TEXTURE_GEN_T);
03515             glDisable(GL_TEXTURE_GEN_R);
03516             glDisable(GL_TEXTURE_GEN_Q);
03517             checkGLcall("Disable texgen.");
03518 
03519             break;
03520     }
03521 
03522     /* Update the texture matrix. */
03523     if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + stage)))
03524         transform_texture(context, state, STATE_TEXTURESTAGE(stage, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
03525 
03526     if (!isStateDirty(context, STATE_VDECL) && context->namedArraysLoaded)
03527     {
03528         /* Reload the arrays if we are using fixed function arrays to reflect the selected coord input
03529          * source. Call loadTexCoords directly because there is no need to reparse the vertex declaration
03530          * and do all the things linked to it
03531          * TODO: Tidy that up to reload only the arrays of the changed unit
03532          */
03533         GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
03534 
03535         unload_tex_coords(gl_info);
03536         load_tex_coords(context, &device->strided_streams, &curVBO, state);
03537     }
03538 }
03539 
03540 static void tex_bumpenvlscale(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03541 {
03542     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
03543     const struct wined3d_shader *ps = state->pixel_shader;
03544 
03545     if (ps && stage && (ps->reg_maps.luminanceparams & (1 << stage)))
03546     {
03547         /* The pixel shader has to know the luminance scale. Do a constants
03548          * update if it isn't scheduled anyway. */
03549         if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
03550                 && !isStateDirty(context, STATE_PIXELSHADER))
03551             shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
03552     }
03553 }
03554 
03555 static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03556 {
03557     const DWORD sampler = state_id - STATE_SAMPLER(0);
03558     const struct wined3d_texture *texture = state->textures[sampler];
03559 
03560     TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
03561 
03562     if(!texture) return;
03563     /* The fixed function np2 texture emulation uses the texture matrix to fix up the coordinates
03564      * wined3d_texture_apply_state_changes() multiplies the set matrix with a fixup matrix. Before the
03565      * scaling is reapplied or removed, the texture matrix has to be reapplied
03566      *
03567      * The mapped stage is already active because the sampler() function below, which is part of the
03568      * misc pipeline
03569      */
03570     if (sampler < MAX_TEXTURES)
03571     {
03572         const BOOL texIsPow2 = !(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT);
03573 
03574         if (texIsPow2 || (context->lastWasPow2Texture & (1 << sampler)))
03575         {
03576             const struct wined3d_device *device = context->swapchain->device;
03577 
03578             if (texIsPow2)
03579                 context->lastWasPow2Texture |= 1 << sampler;
03580             else
03581                 context->lastWasPow2Texture &= ~(1 << sampler);
03582 
03583             transform_texture(context, state,
03584                     STATE_TEXTURESTAGE(device->texUnitMap[sampler], WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
03585         }
03586     }
03587 }
03588 
03589 static void sampler(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03590 {
03591     const struct wined3d_device *device = context->swapchain->device;
03592     DWORD sampler = state_id - STATE_SAMPLER(0);
03593     DWORD mapped_stage = device->texUnitMap[sampler];
03594     const struct wined3d_gl_info *gl_info = context->gl_info;
03595     union {
03596         float f;
03597         DWORD d;
03598     } tmpvalue;
03599 
03600     TRACE("Sampler: %d\n", sampler);
03601     /* Enabling and disabling texture dimensions is done by texture stage state / pixel shader setup, this function
03602      * only has to bind textures and set the per texture states
03603      */
03604 
03605     if (mapped_stage == WINED3D_UNMAPPED_STAGE)
03606     {
03607         TRACE("No sampler mapped to stage %d. Returning.\n", sampler);
03608         return;
03609     }
03610 
03611     if (mapped_stage >= gl_info->limits.combined_samplers)
03612     {
03613         return;
03614     }
03615     context_active_texture(context, gl_info, mapped_stage);
03616 
03617     if (state->textures[sampler])
03618     {
03619         struct wined3d_texture *texture = state->textures[sampler];
03620         BOOL srgb = state->sampler_states[sampler][WINED3D_SAMP_SRGB_TEXTURE];
03621 
03622         texture->texture_ops->texture_bind(texture, context, srgb);
03623         wined3d_texture_apply_state_changes(texture, state->sampler_states[sampler], gl_info);
03624 
03625         if (gl_info->supported[EXT_TEXTURE_LOD_BIAS])
03626         {
03627             tmpvalue.d = state->sampler_states[sampler][WINED3D_SAMP_MIPMAP_LOD_BIAS];
03628             glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT,
03629                       GL_TEXTURE_LOD_BIAS_EXT,
03630                       tmpvalue.f);
03631             checkGLcall("glTexEnvf(GL_TEXTURE_LOD_BIAS_EXT, ...)");
03632         }
03633 
03634         if (!use_ps(state) && sampler < state->lowest_disabled_stage)
03635         {
03636             if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
03637             {
03638                 /* If color keying is enabled update the alpha test, it
03639                  * depends on the existence of a color key in stage 0. */
03640                 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
03641             }
03642         }
03643 
03644         /* Trigger shader constant reloading (for NP2 texcoord fixup) */
03645         if (!(texture->flags & WINED3D_TEXTURE_POW2_MAT_IDENT))
03646             device->shader_backend->shader_load_np2fixup_constants(device->shader_priv, gl_info, state);
03647     }
03648     else
03649     {
03650         if (sampler < state->lowest_disabled_stage)
03651         {
03652             /* TODO: What should I do with pixel shaders here ??? */
03653             if (state->render_states[WINED3D_RS_COLORKEYENABLE] && !sampler)
03654             {
03655                 /* If color keying is enabled update the alpha test, it
03656                  * depends on the existence of a color key in stage 0. */
03657                 state_alpha(context, state, WINED3D_RS_COLORKEYENABLE);
03658             }
03659         } /* Otherwise tex_colorop disables the stage */
03660         context_bind_texture(context, GL_NONE, 0);
03661     }
03662 }
03663 
03664 void apply_pixelshader(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03665 {
03666     const struct wined3d_device *device = context->swapchain->device;
03667     BOOL use_vshader = use_vs(state);
03668     BOOL use_pshader = use_ps(state);
03669     unsigned int i;
03670 
03671     if (use_pshader)
03672     {
03673         if (!context->last_was_pshader)
03674         {
03675             /* Former draw without a pixel shader, some samplers may be
03676              * disabled because of WINED3D_TSS_COLOR_OP = WINED3DTOP_DISABLE
03677              * make sure to enable them. */
03678             for (i = 0; i < MAX_FRAGMENT_SAMPLERS; ++i)
03679             {
03680                 if (!isStateDirty(context, STATE_SAMPLER(i)))
03681                     sampler(context, state, STATE_SAMPLER(i));
03682             }
03683             context->last_was_pshader = TRUE;
03684         }
03685         else
03686         {
03687             /* Otherwise all samplers were activated by the code above in
03688              * earlier draws, or by sampler() if a different texture was
03689              * bound. I don't have to do anything. */
03690         }
03691     }
03692     else
03693     {
03694         /* Disabled the pixel shader - color ops weren't applied while it was
03695          * enabled, so re-apply them. */
03696         for (i = 0; i < context->gl_info->limits.texture_stages; ++i)
03697         {
03698             if (!isStateDirty(context, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP)))
03699                 context_apply_state(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_COLOR_OP));
03700         }
03701         context->last_was_pshader = FALSE;
03702     }
03703 
03704     if (!isStateDirty(context, context->state_table[STATE_VSHADER].representative))
03705     {
03706         device->shader_backend->shader_select(context, use_pshader, use_vshader);
03707 
03708         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && (use_vshader || use_pshader))
03709             shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
03710     }
03711 }
03712 
03713 static void shader_bumpenvmat(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03714 {
03715     DWORD stage = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1);
03716     const struct wined3d_shader *ps = state->pixel_shader;
03717 
03718     if (ps && stage && (ps->reg_maps.bumpmat & (1 << stage)))
03719     {
03720         /* The pixel shader has to know the bump env matrix. Do a constants
03721          * update if it isn't scheduled anyway. */
03722         if (!isStateDirty(context, STATE_PIXELSHADERCONSTANT)
03723                 && !isStateDirty(context, STATE_PIXELSHADER))
03724             shaderconstant(context, state, STATE_PIXELSHADERCONSTANT);
03725     }
03726 }
03727 
03728 static void transform_world(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03729 {
03730     /* This function is called by transform_view below if the view matrix was changed too
03731      *
03732      * Deliberately no check if the vertex declaration is dirty because the vdecl state
03733      * does not always update the world matrix, only on a switch between transformed
03734      * and untransformed draws. It *may* happen that the world matrix is set 2 times during one
03735      * draw, but that should be rather rare and cheaper in total.
03736      */
03737     glMatrixMode(GL_MODELVIEW);
03738     checkGLcall("glMatrixMode");
03739 
03740     if(context->last_was_rhw) {
03741         glLoadIdentity();
03742         checkGLcall("glLoadIdentity()");
03743     }
03744     else
03745     {
03746         /* In the general case, the view matrix is the identity matrix */
03747         if (context->swapchain->device->view_ident)
03748         {
03749             glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
03750             checkGLcall("glLoadMatrixf");
03751         }
03752         else
03753         {
03754             glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
03755             checkGLcall("glLoadMatrixf");
03756             glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(0)].u.m[0][0]);
03757             checkGLcall("glMultMatrixf");
03758         }
03759     }
03760 }
03761 
03762 static void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03763 {
03764     UINT index = state_id - STATE_CLIPPLANE(0);
03765 
03766     if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= context->gl_info->limits.clipplanes)
03767         return;
03768 
03769     glMatrixMode(GL_MODELVIEW);
03770     glPushMatrix();
03771 
03772     /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */
03773     if (!use_vs(state))
03774         glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
03775     else
03776         /* with vertex shaders, clip planes are not transformed in direct3d,
03777          * in OpenGL they are still transformed by the model view.
03778          */
03779         glLoadIdentity();
03780 
03781     TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n",
03782             state->clip_planes[index][0],
03783             state->clip_planes[index][1],
03784             state->clip_planes[index][2],
03785             state->clip_planes[index][3]);
03786     glClipPlane(GL_CLIP_PLANE0 + index, state->clip_planes[index]);
03787     checkGLcall("glClipPlane");
03788 
03789     glPopMatrix();
03790 }
03791 
03792 static void transform_worldex(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03793 {
03794     UINT matrix = state_id - STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0));
03795     GLenum glMat;
03796     TRACE("Setting world matrix %d\n", matrix);
03797 
03798     if (matrix >= context->gl_info->limits.blends)
03799     {
03800         WARN("Unsupported blend matrix set\n");
03801         return;
03802     }
03803 
03804     if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
03805         return;
03806 
03807     /* GL_MODELVIEW0_ARB:  0x1700
03808      * GL_MODELVIEW1_ARB:  0x850a
03809      * GL_MODELVIEW2_ARB:  0x8722
03810      * GL_MODELVIEW3_ARB:  0x8723
03811      * etc
03812      * GL_MODELVIEW31_ARB: 0x873F
03813      */
03814     if(matrix == 1) glMat = GL_MODELVIEW1_ARB;
03815     else glMat = GL_MODELVIEW2_ARB - 2 + matrix;
03816 
03817     glMatrixMode(glMat);
03818     checkGLcall("glMatrixMode(glMat)");
03819 
03820     /* World matrix 0 is multiplied with the view matrix because d3d uses 3
03821      * matrices while gl uses only 2. To avoid weighting the view matrix
03822      * incorrectly it has to be multiplied into every GL modelview matrix. */
03823     if (context->swapchain->device->view_ident)
03824     {
03825         glLoadMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
03826         checkGLcall("glLoadMatrixf");
03827     }
03828     else
03829     {
03830         glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
03831         checkGLcall("glLoadMatrixf");
03832         glMultMatrixf(&state->transforms[WINED3D_TS_WORLD_MATRIX(matrix)].u.m[0][0]);
03833         checkGLcall("glMultMatrixf");
03834     }
03835 }
03836 
03837 static void state_vertexblend_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03838 {
03839     enum wined3d_vertex_blend_flags f = state->render_states[WINED3D_RS_VERTEXBLEND];
03840     static unsigned int once;
03841 
03842     if (f == WINED3D_VBF_DISABLE)
03843         return;
03844 
03845     if (!once++) FIXME("Vertex blend flags %#x not supported.\n", f);
03846     else WARN("Vertex blend flags %#x not supported.\n", f);
03847 }
03848 
03849 static void state_vertexblend(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03850 {
03851     enum wined3d_vertex_blend_flags val = state->render_states[WINED3D_RS_VERTEXBLEND];
03852     struct wined3d_device *device = context->swapchain->device;
03853     const struct wined3d_gl_info *gl_info = context->gl_info;
03854     static unsigned int once;
03855 
03856     switch (val)
03857     {
03858         case WINED3D_VBF_1WEIGHTS:
03859         case WINED3D_VBF_2WEIGHTS:
03860         case WINED3D_VBF_3WEIGHTS:
03861             glEnable(GL_VERTEX_BLEND_ARB);
03862             checkGLcall("glEnable(GL_VERTEX_BLEND_ARB)");
03863 
03864             /* D3D adds one more matrix which has weight (1 - sum(weights)).
03865              * This is enabled at context creation with enabling
03866              * GL_WEIGHT_SUM_UNITY_ARB. */
03867             GL_EXTCALL(glVertexBlendARB(state->render_states[WINED3D_RS_VERTEXBLEND] + 1));
03868 
03869             if (!device->vertexBlendUsed)
03870             {
03871                 unsigned int i;
03872                 for (i = 1; i < gl_info->limits.blends; ++i)
03873                 {
03874                     if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i))))
03875                         transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(i)));
03876                 }
03877                 device->vertexBlendUsed = TRUE;
03878             }
03879             break;
03880 
03881         case WINED3D_VBF_TWEENING:
03882         case WINED3D_VBF_0WEIGHTS: /* Indexed vertex blending, not supported. */
03883             if (!once++) FIXME("Vertex blend flags %#x not supported.\n", val);
03884             else WARN("Vertex blend flags %#x not supported.\n", val);
03885             /* Fall through. */
03886         case WINED3D_VBF_DISABLE:
03887             glDisable(GL_VERTEX_BLEND_ARB);
03888             checkGLcall("glDisable(GL_VERTEX_BLEND_ARB)");
03889             break;
03890     }
03891 }
03892 
03893 static void transform_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03894 {
03895     const struct wined3d_gl_info *gl_info = context->gl_info;
03896     const struct wined3d_light_info *light = NULL;
03897     unsigned int k;
03898 
03899     /* If we are changing the View matrix, reset the light and clipping planes to the new view
03900      * NOTE: We have to reset the positions even if the light/plane is not currently
03901      *       enabled, since the call to enable it will not reset the position.
03902      * NOTE2: Apparently texture transforms do NOT need reapplying
03903      */
03904 
03905     glMatrixMode(GL_MODELVIEW);
03906     checkGLcall("glMatrixMode(GL_MODELVIEW)");
03907     glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
03908     checkGLcall("glLoadMatrixf(...)");
03909 
03910     /* Reset lights. TODO: Call light apply func */
03911     for (k = 0; k < gl_info->limits.lights; ++k)
03912     {
03913         if (!(light = state->lights[k]))
03914             continue;
03915         glLightfv(GL_LIGHT0 + light->glIndex, GL_POSITION, light->lightPosn);
03916         checkGLcall("glLightfv posn");
03917         glLightfv(GL_LIGHT0 + light->glIndex, GL_SPOT_DIRECTION, light->lightDirn);
03918         checkGLcall("glLightfv dirn");
03919     }
03920 
03921     /* Reset Clipping Planes  */
03922     for (k = 0; k < gl_info->limits.clipplanes; ++k)
03923     {
03924         if (!isStateDirty(context, STATE_CLIPPLANE(k)))
03925             clipplane(context, state, STATE_CLIPPLANE(k));
03926     }
03927 
03928     if(context->last_was_rhw) {
03929         glLoadIdentity();
03930         checkGLcall("glLoadIdentity()");
03931         /* No need to update the world matrix, the identity is fine */
03932         return;
03933     }
03934 
03935     /* Call the world matrix state, this will apply the combined WORLD + VIEW matrix
03936      * No need to do it here if the state is scheduled for update. */
03937     if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
03938         transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
03939 
03940     /* Avoid looping over a number of matrices if the app never used the functionality */
03941     if (context->swapchain->device->vertexBlendUsed)
03942     {
03943         for (k = 1; k < gl_info->limits.blends; ++k)
03944         {
03945             if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k))))
03946                 transform_worldex(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(k)));
03947         }
03948     }
03949 }
03950 
03951 static void transform_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
03952 {
03953     glMatrixMode(GL_PROJECTION);
03954     checkGLcall("glMatrixMode(GL_PROJECTION)");
03955 
03956     /* There are a couple of additional things we have to take into account
03957      * here besides the projection transformation itself:
03958      *   - We need to flip along the y-axis in case of offscreen rendering.
03959      *   - OpenGL Z range is {-Wc,...,Wc} while D3D Z range is {0,...,Wc}.
03960      *   - D3D coordinates refer to pixel centers while GL coordinates refer
03961      *     to pixel corners.
03962      *   - D3D has a top-left filling convention. We need to maintain this
03963      *     even after the y-flip mentioned above.
03964      * In order to handle the last two points, we translate by
03965      * (63.0 / 128.0) / VPw and (63.0 / 128.0) / VPh. This is equivalent to
03966      * translating slightly less than half a pixel. We want the difference to
03967      * be large enough that it doesn't get lost due to rounding inside the
03968      * driver, but small enough to prevent it from interfering with any
03969      * anti-aliasing. */
03970 
03971     if (context->last_was_rhw)
03972     {
03973         /* Transform D3D RHW coordinates to OpenGL clip coordinates. */
03974         double x = state->viewport.x;
03975         double y = state->viewport.y;
03976         double w = state->viewport.width;
03977         double h = state->viewport.height;
03978         double x_scale = 2.0 / w;
03979         double x_offset = ((63.0 / 64.0) - (2.0 * x) - w) / w;
03980         double y_scale = context->render_offscreen ? 2.0 / h : 2.0 / -h;
03981         double y_offset = context->render_offscreen
03982                 ? ((63.0 / 64.0) - (2.0 * y) - h) / h
03983                 : ((63.0 / 64.0) - (2.0 * y) - h) / -h;
03984         const GLdouble projection[] =
03985         {
03986              x_scale,      0.0,  0.0, 0.0,
03987                  0.0,  y_scale,  0.0, 0.0,
03988                  0.0,      0.0,  2.0, 0.0,
03989             x_offset, y_offset, -1.0, 1.0,
03990         };
03991 
03992         glLoadMatrixd(projection);
03993         checkGLcall("glLoadMatrixd");
03994     }
03995     else
03996     {
03997         double y_scale = context->render_offscreen ? -1.0 : 1.0;
03998         double x_offset = (63.0 / 64.0) / state->viewport.width;
03999         double y_offset = context->render_offscreen
04000                 ? (63.0 / 64.0) / state->viewport.height
04001                 : -(63.0 / 64.0) / state->viewport.height;
04002         const GLdouble projection[] =
04003         {
04004                  1.0,      0.0,  0.0, 0.0,
04005                  0.0,  y_scale,  0.0, 0.0,
04006                  0.0,      0.0,  2.0, 0.0,
04007             x_offset, y_offset, -1.0, 1.0,
04008         };
04009 
04010         glLoadMatrixd(projection);
04011         checkGLcall("glLoadMatrixd");
04012 
04013         glMultMatrixf(&state->transforms[WINED3D_TS_PROJECTION].u.m[0][0]);
04014         checkGLcall("glLoadMatrixf");
04015     }
04016 }
04017 
04018 /* This should match any arrays loaded in load_vertex_data.
04019  * TODO: Only load / unload arrays if we have to. */
04020 static void unload_vertex_data(const struct wined3d_gl_info *gl_info)
04021 {
04022     glDisableClientState(GL_VERTEX_ARRAY);
04023     glDisableClientState(GL_NORMAL_ARRAY);
04024     glDisableClientState(GL_COLOR_ARRAY);
04025     if (gl_info->supported[EXT_SECONDARY_COLOR])
04026     {
04027         glDisableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
04028     }
04029     if (gl_info->supported[ARB_VERTEX_BLEND])
04030     {
04031         glDisableClientState(GL_WEIGHT_ARRAY_ARB);
04032     }
04033     unload_tex_coords(gl_info);
04034 }
04035 
04036 static inline void unload_numbered_array(struct wined3d_context *context, int i)
04037 {
04038     const struct wined3d_gl_info *gl_info = context->gl_info;
04039 
04040     GL_EXTCALL(glDisableVertexAttribArrayARB(i));
04041     checkGLcall("glDisableVertexAttribArrayARB(reg)");
04042 
04043     context->numbered_array_mask &= ~(1 << i);
04044 }
04045 
04046 /* This should match any arrays loaded in loadNumberedArrays
04047  * TODO: Only load / unload arrays if we have to. */
04048 static void unload_numbered_arrays(struct wined3d_context *context)
04049 {
04050     /* disable any attribs (this is the same for both GLSL and ARB modes) */
04051     int i;
04052 
04053     for (i = 0; i < context->gl_info->limits.vertex_attribs; ++i) {
04054         unload_numbered_array(context, i);
04055     }
04056 }
04057 
04058 static void load_numbered_arrays(struct wined3d_context *context,
04059         const struct wined3d_stream_info *stream_info, const struct wined3d_state *state)
04060 {
04061     struct wined3d_device *device = context->swapchain->device;
04062     const struct wined3d_gl_info *gl_info = context->gl_info;
04063     GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
04064     int i;
04065 
04066     /* Default to no instancing */
04067     device->instancedDraw = FALSE;
04068 
04069     for (i = 0; i < MAX_ATTRIBS; i++)
04070     {
04071         const struct wined3d_stream_state *stream;
04072 
04073         if (!(stream_info->use_map & (1 << i)))
04074         {
04075             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
04076             continue;
04077         }
04078 
04079         stream = &state->streams[stream_info->elements[i].stream_idx];
04080 
04081         /* Do not load instance data. It will be specified using glTexCoord by drawprim */
04082         if (stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA)
04083         {
04084             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
04085             device->instancedDraw = TRUE;
04086             continue;
04087         }
04088 
04089         TRACE_(d3d_shader)("Loading array %u [VBO=%u]\n", i, stream_info->elements[i].data.buffer_object);
04090 
04091         if (stream_info->elements[i].stride)
04092         {
04093             if (curVBO != stream_info->elements[i].data.buffer_object)
04094             {
04095                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, stream_info->elements[i].data.buffer_object));
04096                 checkGLcall("glBindBufferARB");
04097                 curVBO = stream_info->elements[i].data.buffer_object;
04098             }
04099             /* Use the VBO to find out if a vertex buffer exists, not the vb
04100              * pointer. vb can point to a user pointer data blob. In that case
04101              * curVBO will be 0. If there is a vertex buffer but no vbo we
04102              * won't be load converted attributes anyway. */
04103             GL_EXTCALL(glVertexAttribPointerARB(i, stream_info->elements[i].format->gl_vtx_format,
04104                     stream_info->elements[i].format->gl_vtx_type,
04105                     stream_info->elements[i].format->gl_normalized,
04106                     stream_info->elements[i].stride, stream_info->elements[i].data.addr
04107                     + state->load_base_vertex_index * stream_info->elements[i].stride));
04108 
04109             if (!(context->numbered_array_mask & (1 << i)))
04110             {
04111                 GL_EXTCALL(glEnableVertexAttribArrayARB(i));
04112                 context->numbered_array_mask |= (1 << i);
04113             }
04114         }
04115         else
04116         {
04117             /* Stride = 0 means always the same values.
04118              * glVertexAttribPointerARB doesn't do that. Instead disable the
04119              * pointer and set up the attribute statically. But we have to
04120              * figure out the system memory address. */
04121             const BYTE *ptr = stream_info->elements[i].data.addr;
04122             if (stream_info->elements[i].data.buffer_object)
04123             {
04124                 ptr += (ULONG_PTR)buffer_get_sysmem(stream->buffer, gl_info);
04125             }
04126 
04127             if (context->numbered_array_mask & (1 << i)) unload_numbered_array(context, i);
04128 
04129             switch (stream_info->elements[i].format->id)
04130             {
04131                 case WINED3DFMT_R32_FLOAT:
04132                     GL_EXTCALL(glVertexAttrib1fvARB(i, (const GLfloat *)ptr));
04133                     break;
04134                 case WINED3DFMT_R32G32_FLOAT:
04135                     GL_EXTCALL(glVertexAttrib2fvARB(i, (const GLfloat *)ptr));
04136                     break;
04137                 case WINED3DFMT_R32G32B32_FLOAT:
04138                     GL_EXTCALL(glVertexAttrib3fvARB(i, (const GLfloat *)ptr));
04139                     break;
04140                 case WINED3DFMT_R32G32B32A32_FLOAT:
04141                     GL_EXTCALL(glVertexAttrib4fvARB(i, (const GLfloat *)ptr));
04142                     break;
04143 
04144                 case WINED3DFMT_R8G8B8A8_UINT:
04145                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
04146                     break;
04147                 case WINED3DFMT_B8G8R8A8_UNORM:
04148                     if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
04149                     {
04150                         const DWORD *src = (const DWORD *)ptr;
04151                         DWORD c = *src & 0xff00ff00;
04152                         c |= (*src & 0xff0000) >> 16;
04153                         c |= (*src & 0xff) << 16;
04154                         GL_EXTCALL(glVertexAttrib4NubvARB(i, (GLubyte *)&c));
04155                         break;
04156                     }
04157                     /* else fallthrough */
04158                 case WINED3DFMT_R8G8B8A8_UNORM:
04159                     GL_EXTCALL(glVertexAttrib4NubvARB(i, ptr));
04160                     break;
04161 
04162                 case WINED3DFMT_R16G16_SINT:
04163                     GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
04164                     break;
04165                 case WINED3DFMT_R16G16B16A16_SINT:
04166                     GL_EXTCALL(glVertexAttrib4svARB(i, (const GLshort *)ptr));
04167                     break;
04168 
04169                 case WINED3DFMT_R16G16_SNORM:
04170                 {
04171                     const GLshort s[4] = {((const GLshort *)ptr)[0], ((const GLshort *)ptr)[1], 0, 1};
04172                     GL_EXTCALL(glVertexAttrib4NsvARB(i, s));
04173                     break;
04174                 }
04175                 case WINED3DFMT_R16G16_UNORM:
04176                 {
04177                     const GLushort s[4] = {((const GLushort *)ptr)[0], ((const GLushort *)ptr)[1], 0, 1};
04178                     GL_EXTCALL(glVertexAttrib4NusvARB(i, s));
04179                     break;
04180                 }
04181                 case WINED3DFMT_R16G16B16A16_SNORM:
04182                     GL_EXTCALL(glVertexAttrib4NsvARB(i, (const GLshort *)ptr));
04183                     break;
04184                 case WINED3DFMT_R16G16B16A16_UNORM:
04185                     GL_EXTCALL(glVertexAttrib4NusvARB(i, (const GLushort *)ptr));
04186                     break;
04187 
04188                 case WINED3DFMT_R10G10B10A2_UINT:
04189                     FIXME("Unsure about WINED3DDECLTYPE_UDEC3\n");
04190                     /*glVertexAttrib3usvARB(i, (const GLushort *)ptr); Does not exist */
04191                     break;
04192                 case WINED3DFMT_R10G10B10A2_SNORM:
04193                     FIXME("Unsure about WINED3DDECLTYPE_DEC3N\n");
04194                     /*glVertexAttrib3NusvARB(i, (const GLushort *)ptr); Does not exist */
04195                     break;
04196 
04197                 case WINED3DFMT_R16G16_FLOAT:
04198                     /* Are those 16 bit floats. C doesn't have a 16 bit float type. I could read the single bits and calculate a 4
04199                      * byte float according to the IEEE standard
04200                      */
04201                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_2\n");
04202                     break;
04203                 case WINED3DFMT_R16G16B16A16_FLOAT:
04204                     FIXME("Unsupported WINED3DDECLTYPE_FLOAT16_4\n");
04205                     break;
04206 
04207                 default:
04208                     ERR("Unexpected declaration in stride 0 attributes\n");
04209                     break;
04210 
04211             }
04212         }
04213     }
04214     checkGLcall("Loading numbered arrays");
04215 }
04216 
04217 static void load_vertex_data(const struct wined3d_context *context,
04218         const struct wined3d_stream_info *si, const struct wined3d_state *state)
04219 {
04220     struct wined3d_device *device = context->swapchain->device;
04221     const struct wined3d_gl_info *gl_info = context->gl_info;
04222     GLuint curVBO = gl_info->supported[ARB_VERTEX_BUFFER_OBJECT] ? ~0U : 0;
04223     const struct wined3d_stream_info_element *e;
04224 
04225     TRACE("Using fast vertex array code\n");
04226 
04227     /* This is fixed function pipeline only, and the fixed function pipeline doesn't do instancing */
04228     device->instancedDraw = FALSE;
04229 
04230     /* Blend Data ---------------------------------------------- */
04231     if ((si->use_map & (1 << WINED3D_FFP_BLENDWEIGHT))
04232             || si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
04233     {
04234         e = &si->elements[WINED3D_FFP_BLENDWEIGHT];
04235 
04236         if (gl_info->supported[ARB_VERTEX_BLEND])
04237         {
04238             TRACE("Blend %u %p %u\n", e->format->component_count,
04239                     e->data.addr + state->load_base_vertex_index * e->stride, e->stride);
04240 
04241             glEnableClientState(GL_WEIGHT_ARRAY_ARB);
04242             checkGLcall("glEnableClientState(GL_WEIGHT_ARRAY_ARB)");
04243 
04244             GL_EXTCALL(glVertexBlendARB(e->format->component_count + 1));
04245 
04246             if (curVBO != e->data.buffer_object)
04247             {
04248                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
04249                 checkGLcall("glBindBufferARB");
04250                 curVBO = e->data.buffer_object;
04251             }
04252 
04253             TRACE("glWeightPointerARB(%#x, %#x, %#x, %p);\n",
04254                     e->format->gl_vtx_format,
04255                     e->format->gl_vtx_type,
04256                     e->stride,
04257                     e->data.addr + state->load_base_vertex_index * e->stride);
04258             GL_EXTCALL(glWeightPointerARB(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
04259                     e->data.addr + state->load_base_vertex_index * e->stride));
04260 
04261             checkGLcall("glWeightPointerARB");
04262 
04263             if (si->use_map & (1 << WINED3D_FFP_BLENDINDICES))
04264             {
04265                 static BOOL warned;
04266                 if (!warned)
04267                 {
04268                     FIXME("blendMatrixIndices support\n");
04269                     warned = TRUE;
04270                 }
04271             }
04272         } else {
04273             /* TODO: support blends in drawStridedSlow
04274              * No need to write a FIXME here, this is done after the general vertex decl decoding
04275              */
04276             WARN("unsupported blending in openGl\n");
04277         }
04278     }
04279     else
04280     {
04281         if (gl_info->supported[ARB_VERTEX_BLEND])
04282         {
04283             static const GLbyte one = 1;
04284             GL_EXTCALL(glWeightbvARB(1, &one));
04285             checkGLcall("glWeightbvARB(gl_info->max_blends, weights)");
04286         }
04287     }
04288 
04289     /* Point Size ----------------------------------------------*/
04290     if (si->use_map & (1 << WINED3D_FFP_PSIZE))
04291     {
04292         /* no such functionality in the fixed function GL pipeline */
04293         TRACE("Cannot change ptSize here in openGl\n");
04294         /* TODO: Implement this function in using shaders if they are available */
04295     }
04296 
04297     /* Vertex Pointers -----------------------------------------*/
04298     if (si->use_map & (1 << WINED3D_FFP_POSITION))
04299     {
04300         e = &si->elements[WINED3D_FFP_POSITION];
04301 
04302         if (curVBO != e->data.buffer_object)
04303         {
04304             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
04305             checkGLcall("glBindBufferARB");
04306             curVBO = e->data.buffer_object;
04307         }
04308 
04309         /* min(WINED3D_ATR_FORMAT(position),3) to Disable RHW mode as 'w' coord
04310            handling for rhw mode should not impact screen position whereas in GL it does.
04311            This may result in very slightly distorted textures in rhw mode.
04312            There's always the other option of fixing the view matrix to
04313            prevent w from having any effect.
04314 
04315            This only applies to user pointer sources, in VBOs the vertices are fixed up
04316          */
04317         if (!e->data.buffer_object)
04318         {
04319             TRACE("glVertexPointer(3, %#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
04320                     e->data.addr + state->load_base_vertex_index * e->stride);
04321             glVertexPointer(3 /* min(e->format->gl_vtx_format, 3) */, e->format->gl_vtx_type, e->stride,
04322                     e->data.addr + state->load_base_vertex_index * e->stride);
04323         }
04324         else
04325         {
04326             TRACE("glVertexPointer(%#x, %#x, %#x, %p);\n",
04327                     e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
04328                     e->data.addr + state->load_base_vertex_index * e->stride);
04329             glVertexPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
04330                     e->data.addr + state->load_base_vertex_index * e->stride);
04331         }
04332         checkGLcall("glVertexPointer(...)");
04333         glEnableClientState(GL_VERTEX_ARRAY);
04334         checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
04335     }
04336 
04337     /* Normals -------------------------------------------------*/
04338     if (si->use_map & (1 << WINED3D_FFP_NORMAL))
04339     {
04340         e = &si->elements[WINED3D_FFP_NORMAL];
04341 
04342         if (curVBO != e->data.buffer_object)
04343         {
04344             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
04345             checkGLcall("glBindBufferARB");
04346             curVBO = e->data.buffer_object;
04347         }
04348 
04349         TRACE("glNormalPointer(%#x, %#x, %p);\n", e->format->gl_vtx_type, e->stride,
04350                 e->data.addr + state->load_base_vertex_index * e->stride);
04351         glNormalPointer(e->format->gl_vtx_type, e->stride,
04352                 e->data.addr + state->load_base_vertex_index * e->stride);
04353         checkGLcall("glNormalPointer(...)");
04354         glEnableClientState(GL_NORMAL_ARRAY);
04355         checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
04356 
04357     } else {
04358         glNormal3f(0, 0, 0);
04359         checkGLcall("glNormal3f(0, 0, 0)");
04360     }
04361 
04362     /* Diffuse Colour --------------------------------------------*/
04363     /*  WARNING: Data here MUST be in RGBA format, so cannot      */
04364     /*     go directly into fast mode from app pgm, because       */
04365     /*     directx requires data in BGRA format.                  */
04366     /* currently fixupVertices swizzles the format, but this isn't*/
04367     /* very practical when using VBOs                             */
04368     /* NOTE: Unless we write a vertex shader to swizzle the colour*/
04369     /* , or the user doesn't care and wants the speed advantage   */
04370 
04371     if (si->use_map & (1 << WINED3D_FFP_DIFFUSE))
04372     {
04373         e = &si->elements[WINED3D_FFP_DIFFUSE];
04374 
04375         if (curVBO != e->data.buffer_object)
04376         {
04377             GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
04378             checkGLcall("glBindBufferARB");
04379             curVBO = e->data.buffer_object;
04380         }
04381 
04382         TRACE("glColorPointer(%#x, %#x %#x, %p);\n",
04383                 e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
04384                 e->data.addr + state->load_base_vertex_index * e->stride);
04385         glColorPointer(e->format->gl_vtx_format, e->format->gl_vtx_type, e->stride,
04386                 e->data.addr + state->load_base_vertex_index * e->stride);
04387         checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
04388         glEnableClientState(GL_COLOR_ARRAY);
04389         checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
04390 
04391     } else {
04392         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
04393         checkGLcall("glColor4f(1, 1, 1, 1)");
04394     }
04395 
04396     /* Specular Colour ------------------------------------------*/
04397     if (si->use_map & (1 << WINED3D_FFP_SPECULAR))
04398     {
04399         TRACE("setting specular colour\n");
04400 
04401         e = &si->elements[WINED3D_FFP_SPECULAR];
04402 
04403         if (gl_info->supported[EXT_SECONDARY_COLOR])
04404         {
04405             GLenum type = e->format->gl_vtx_type;
04406             GLint format = e->format->gl_vtx_format;
04407 
04408             if (curVBO != e->data.buffer_object)
04409             {
04410                 GL_EXTCALL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, e->data.buffer_object));
04411                 checkGLcall("glBindBufferARB");
04412                 curVBO = e->data.buffer_object;
04413             }
04414 
04415             if (format != 4 || (gl_info->quirks & WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA))
04416             {
04417                 /* Usually specular colors only allow 3 components, since they have no alpha. In D3D, the specular alpha
04418                  * contains the fog coordinate, which is passed to GL with GL_EXT_fog_coord. However, the fixed function
04419                  * vertex pipeline can pass the specular alpha through, and pixel shaders can read it. So it GL accepts
04420                  * 4 component secondary colors use it
04421                  */
04422                 TRACE("glSecondaryColorPointer(%#x, %#x, %#x, %p);\n", format, type, e->stride,
04423                         e->data.addr + state->load_base_vertex_index * e->stride);
04424                 GL_EXTCALL(glSecondaryColorPointerEXT(format, type, e->stride,
04425                         e->data.addr + state->load_base_vertex_index * e->stride));
04426                 checkGLcall("glSecondaryColorPointerEXT(format, type, ...)");
04427             }
04428             else
04429             {
04430                 switch(type)
04431                 {
04432                     case GL_UNSIGNED_BYTE:
04433                         TRACE("glSecondaryColorPointer(3, GL_UNSIGNED_BYTE, %#x, %p);\n", e->stride,
04434                                 e->data.addr + state->load_base_vertex_index * e->stride);
04435                         GL_EXTCALL(glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, e->stride,
04436                                 e->data.addr + state->load_base_vertex_index * e->stride));
04437                         checkGLcall("glSecondaryColorPointerEXT(3, GL_UNSIGNED_BYTE, ...)");
04438                         break;
04439 
04440                     default:
04441                         FIXME("Add 4 component specular color pointers for type %x\n", type);
04442                         /* Make sure that the right color component is dropped */
04443                         TRACE("glSecondaryColorPointer(3, %#x, %#x, %p);\n", type, e->stride,
04444                                 e->data.addr + state->load_base_vertex_index * e->stride);
04445                         GL_EXTCALL(glSecondaryColorPointerEXT(3, type, e->stride,
04446                                 e->data.addr + state->load_base_vertex_index * e->stride));
04447                         checkGLcall("glSecondaryColorPointerEXT(3, type, ...)");
04448                 }
04449             }
04450             glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
04451             checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
04452         }
04453         else
04454         {
04455             WARN("Specular colour is not supported in this GL implementation.\n");
04456         }
04457     }
04458     else
04459     {
04460         if (gl_info->supported[EXT_SECONDARY_COLOR])
04461         {
04462             GL_EXTCALL(glSecondaryColor3fEXT)(0, 0, 0);
04463             checkGLcall("glSecondaryColor3fEXT(0, 0, 0)");
04464         }
04465         else
04466         {
04467             WARN("Specular colour is not supported in this GL implementation.\n");
04468         }
04469     }
04470 
04471     /* Texture coords -------------------------------------------*/
04472     load_tex_coords(context, si, &curVBO, state);
04473 }
04474 
04475 static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04476 {
04477     const struct wined3d_device *device = context->swapchain->device;
04478     BOOL load_numbered = use_vs(state) && !device->useDrawStridedSlow;
04479     BOOL load_named = !use_vs(state) && !device->useDrawStridedSlow;
04480 
04481     if (isStateDirty(context, STATE_VDECL)) return;
04482     if (context->numberedArraysLoaded && !load_numbered)
04483     {
04484         unload_numbered_arrays(context);
04485         context->numberedArraysLoaded = FALSE;
04486         context->numbered_array_mask = 0;
04487     }
04488     else if (context->namedArraysLoaded)
04489     {
04490         unload_vertex_data(context->gl_info);
04491         context->namedArraysLoaded = FALSE;
04492     }
04493 
04494     if (load_numbered)
04495     {
04496         TRACE("Loading numbered arrays\n");
04497         load_numbered_arrays(context, &device->strided_streams, state);
04498         context->numberedArraysLoaded = TRUE;
04499     }
04500     else if (load_named)
04501     {
04502         TRACE("Loading vertex data\n");
04503         load_vertex_data(context, &device->strided_streams, state);
04504         context->namedArraysLoaded = TRUE;
04505     }
04506 }
04507 
04508 static void vdecl_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04509 {
04510     if (isStateDirty(context, STATE_STREAMSRC))
04511         return;
04512     streamsrc(context, state, STATE_STREAMSRC);
04513 }
04514 
04515 static void vertexdeclaration(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04516 {
04517     const struct wined3d_device *device = context->swapchain->device;
04518     const struct wined3d_gl_info *gl_info = context->gl_info;
04519     BOOL useVertexShaderFunction = use_vs(state);
04520     BOOL usePixelShaderFunction = use_ps(state);
04521     BOOL updateFog = FALSE;
04522     BOOL transformed;
04523     BOOL wasrhw = context->last_was_rhw;
04524     unsigned int i;
04525 
04526     transformed = device->strided_streams.position_transformed;
04527     if (transformed != context->last_was_rhw && !useVertexShaderFunction)
04528         updateFog = TRUE;
04529 
04530     context->last_was_rhw = transformed;
04531 
04532     /* Don't have to apply the matrices when vertex shaders are used. When
04533      * vshaders are turned off this function will be called again anyway to
04534      * make sure they're properly set. */
04535     if (!useVertexShaderFunction)
04536     {
04537         /* TODO: Move this mainly to the viewport state and only apply when
04538          * the vp has changed or transformed / untransformed was switched. */
04539         if (wasrhw != context->last_was_rhw
04540                 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION))
04541                 && !isStateDirty(context, STATE_VIEWPORT))
04542             transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
04543         /* World matrix needs reapplication here only if we're switching between rhw and non-rhw
04544          * mode.
04545          *
04546          * If a vertex shader is used, the world matrix changed and then vertex shader unbound
04547          * this check will fail and the matrix not applied again. This is OK because a simple
04548          * world matrix change reapplies the matrix - These checks here are only to satisfy the
04549          * needs of the vertex declaration.
04550          *
04551          * World and view matrix go into the same gl matrix, so only apply them when neither is
04552          * dirty
04553          */
04554         if (transformed != wasrhw && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)))
04555                 && !isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)))
04556             transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
04557         if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_COLORVERTEX)))
04558             state_colormat(context, state, STATE_RENDER(WINED3D_RS_COLORVERTEX));
04559         if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING)))
04560             state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING));
04561 
04562         if (context->last_was_vshader)
04563         {
04564             updateFog = TRUE;
04565 
04566             if (!device->vs_clipping && !isStateDirty(context, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE)))
04567                 state_clipping(context, state, STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE));
04568 
04569             for (i = 0; i < gl_info->limits.clipplanes; ++i)
04570             {
04571                 clipplane(context, state, STATE_CLIPPLANE(i));
04572             }
04573         }
04574         if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS)))
04575             state_normalize(context, state, STATE_RENDER(WINED3D_RS_NORMALIZENORMALS));
04576     }
04577     else
04578     {
04579         if(!context->last_was_vshader) {
04580             static BOOL warned = FALSE;
04581             if(!device->vs_clipping) {
04582                 /* Disable all clip planes to get defined results on all drivers. See comment in the
04583                  * state_clipping state handler
04584                  */
04585                 for (i = 0; i < gl_info->limits.clipplanes; ++i)
04586                 {
04587                     glDisable(GL_CLIP_PLANE0 + i);
04588                     checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
04589                 }
04590 
04591                 if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
04592                 {
04593                     FIXME("Clipping not supported with vertex shaders\n");
04594                     warned = TRUE;
04595                 }
04596             }
04597             if (wasrhw)
04598             {
04599                 /* Apply the transform matrices when switching from rhw
04600                  * drawing to vertex shaders. Vertex shaders themselves do
04601                  * not need it, but the matrices are not reapplied
04602                  * automatically when switching back from vertex shaders to
04603                  * fixed function processing. So make sure we leave the fixed
04604                  * function vertex processing states back in a sane state
04605                  * before switching to shaders. */
04606                 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
04607                     transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
04608                 if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0))))
04609                     transform_world(context, state, STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)));
04610             }
04611             updateFog = TRUE;
04612 
04613             /* Vertex shader clipping ignores the view matrix. Update all clipplanes
04614              * (Note: ARB shaders can read the clip planes for clipping emulation even if
04615              * device->vs_clipping is false.
04616              */
04617             for (i = 0; i < gl_info->limits.clipplanes; ++i)
04618             {
04619                 clipplane(context, state, STATE_CLIPPLANE(i));
04620             }
04621         }
04622     }
04623 
04624     /* Vertex and pixel shaders are applied together, so let the last dirty
04625      * state do the application. */
04626     if (!isStateDirty(context, STATE_PIXELSHADER))
04627     {
04628         device->shader_backend->shader_select(context, usePixelShaderFunction, useVertexShaderFunction);
04629 
04630         if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT)
04631                 && (useVertexShaderFunction || usePixelShaderFunction))
04632             shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
04633     }
04634 
04635     context->last_was_vshader = useVertexShaderFunction;
04636 
04637     if (updateFog)
04638         context_apply_state(context, state, STATE_RENDER(WINED3D_RS_FOGVERTEXMODE));
04639 
04640     if (!useVertexShaderFunction)
04641     {
04642         unsigned int i;
04643 
04644         for (i = 0; i < MAX_TEXTURES; ++i)
04645         {
04646             if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i)))
04647                 transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS));
04648         }
04649     }
04650 }
04651 
04652 static void viewport_miscpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04653 {
04654     const struct wined3d_surface *target = state->fb->render_targets[0];
04655     struct wined3d_viewport vp = state->viewport;
04656 
04657     if (vp.width > target->resource.width)
04658         vp.width = target->resource.width;
04659     if (vp.height > target->resource.height)
04660         vp.height = target->resource.height;
04661 
04662     glDepthRange(vp.min_z, vp.max_z);
04663     checkGLcall("glDepthRange");
04664     /* Note: GL requires lower left, DirectX supplies upper left. This is
04665      * reversed when using offscreen rendering. */
04666     if (context->render_offscreen)
04667     {
04668         glViewport(vp.x, vp.y, vp.width, vp.height);
04669     }
04670     else
04671     {
04672         UINT width, height;
04673 
04674         target->get_drawable_size(context, &width, &height);
04675         glViewport(vp.x, (height - (vp.y + vp.height)),
04676                 vp.width, vp.height);
04677     }
04678 
04679     checkGLcall("glViewport");
04680 }
04681 
04682 static void viewport_vertexpart(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04683 {
04684     if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_PROJECTION)))
04685         transform_projection(context, state, STATE_TRANSFORM(WINED3D_TS_PROJECTION));
04686     if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE)))
04687         state_pscale(context, state, STATE_RENDER(WINED3D_RS_POINTSCALEENABLE));
04688     /* Update the position fixup. */
04689     if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT))
04690         shaderconstant(context, state, STATE_VERTEXSHADERCONSTANT);
04691 }
04692 
04693 static void light(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04694 {
04695     UINT Index = state_id - STATE_ACTIVELIGHT(0);
04696     const struct wined3d_light_info *lightInfo = state->lights[Index];
04697 
04698     if (!lightInfo)
04699     {
04700         glDisable(GL_LIGHT0 + Index);
04701         checkGLcall("glDisable(GL_LIGHT0 + Index)");
04702     }
04703     else
04704     {
04705         float quad_att;
04706         float colRGBA[] = {0.0f, 0.0f, 0.0f, 0.0f};
04707 
04708         /* Light settings are affected by the model view in OpenGL, the View transform in direct3d*/
04709         glMatrixMode(GL_MODELVIEW);
04710         glPushMatrix();
04711         glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW].u.m[0][0]);
04712 
04713         /* Diffuse: */
04714         colRGBA[0] = lightInfo->OriginalParms.diffuse.r;
04715         colRGBA[1] = lightInfo->OriginalParms.diffuse.g;
04716         colRGBA[2] = lightInfo->OriginalParms.diffuse.b;
04717         colRGBA[3] = lightInfo->OriginalParms.diffuse.a;
04718         glLightfv(GL_LIGHT0 + Index, GL_DIFFUSE, colRGBA);
04719         checkGLcall("glLightfv");
04720 
04721         /* Specular */
04722         colRGBA[0] = lightInfo->OriginalParms.specular.r;
04723         colRGBA[1] = lightInfo->OriginalParms.specular.g;
04724         colRGBA[2] = lightInfo->OriginalParms.specular.b;
04725         colRGBA[3] = lightInfo->OriginalParms.specular.a;
04726         glLightfv(GL_LIGHT0 + Index, GL_SPECULAR, colRGBA);
04727         checkGLcall("glLightfv");
04728 
04729         /* Ambient */
04730         colRGBA[0] = lightInfo->OriginalParms.ambient.r;
04731         colRGBA[1] = lightInfo->OriginalParms.ambient.g;
04732         colRGBA[2] = lightInfo->OriginalParms.ambient.b;
04733         colRGBA[3] = lightInfo->OriginalParms.ambient.a;
04734         glLightfv(GL_LIGHT0 + Index, GL_AMBIENT, colRGBA);
04735         checkGLcall("glLightfv");
04736 
04737         if ((lightInfo->OriginalParms.range * lightInfo->OriginalParms.range) >= FLT_MIN)
04738             quad_att = 1.4f / (lightInfo->OriginalParms.range * lightInfo->OriginalParms.range);
04739         else
04740             quad_att = 0.0f; /*  0 or  MAX?  (0 seems to be ok) */
04741 
04742         /* Do not assign attenuation values for lights that do not use them. D3D apps are free to pass any junk,
04743          * but gl drivers use them and may crash due to bad Attenuation values. Need for Speed most wanted sets
04744          * Attenuation0 to NaN and crashes in the gl lib
04745          */
04746 
04747         switch (lightInfo->OriginalParms.type)
04748         {
04749             case WINED3D_LIGHT_POINT:
04750                 /* Position */
04751                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
04752                 checkGLcall("glLightfv");
04753                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
04754                 checkGLcall("glLightf");
04755                 /* Attenuation - Are these right? guessing... */
04756                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
04757                 checkGLcall("glLightf");
04758                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
04759                 checkGLcall("glLightf");
04760                 if (quad_att < lightInfo->OriginalParms.attenuation2)
04761                     quad_att = lightInfo->OriginalParms.attenuation2;
04762                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
04763                 checkGLcall("glLightf");
04764                 /* FIXME: Range */
04765                 break;
04766 
04767             case WINED3D_LIGHT_SPOT:
04768                 /* Position */
04769                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]);
04770                 checkGLcall("glLightfv");
04771                 /* Direction */
04772                 glLightfv(GL_LIGHT0 + Index, GL_SPOT_DIRECTION, &lightInfo->lightDirn[0]);
04773                 checkGLcall("glLightfv");
04774                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, lightInfo->exponent);
04775                 checkGLcall("glLightf");
04776                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
04777                 checkGLcall("glLightf");
04778                 /* Attenuation - Are these right? guessing... */
04779                 glLightf(GL_LIGHT0 + Index, GL_CONSTANT_ATTENUATION, lightInfo->OriginalParms.attenuation0);
04780                 checkGLcall("glLightf");
04781                 glLightf(GL_LIGHT0 + Index, GL_LINEAR_ATTENUATION, lightInfo->OriginalParms.attenuation1);
04782                 checkGLcall("glLightf");
04783                 if (quad_att < lightInfo->OriginalParms.attenuation2)
04784                     quad_att = lightInfo->OriginalParms.attenuation2;
04785                 glLightf(GL_LIGHT0 + Index, GL_QUADRATIC_ATTENUATION, quad_att);
04786                 checkGLcall("glLightf");
04787                 /* FIXME: Range */
04788                 break;
04789 
04790             case WINED3D_LIGHT_DIRECTIONAL:
04791                 /* Direction */
04792                 glLightfv(GL_LIGHT0 + Index, GL_POSITION, &lightInfo->lightPosn[0]); /* Note gl uses w position of 0 for direction! */
04793                 checkGLcall("glLightfv");
04794                 glLightf(GL_LIGHT0 + Index, GL_SPOT_CUTOFF, lightInfo->cutoff);
04795                 checkGLcall("glLightf");
04796                 glLightf(GL_LIGHT0 + Index, GL_SPOT_EXPONENT, 0.0f);
04797                 checkGLcall("glLightf");
04798                 break;
04799 
04800             default:
04801                 FIXME("Unrecognized light type %#x.\n", lightInfo->OriginalParms.type);
04802         }
04803 
04804         /* Restore the modelview matrix */
04805         glPopMatrix();
04806 
04807         glEnable(GL_LIGHT0 + Index);
04808         checkGLcall("glEnable(GL_LIGHT0 + Index)");
04809     }
04810 }
04811 
04812 static void scissorrect(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04813 {
04814     const RECT *r = &state->scissor_rect;
04815 
04816     /* Warning: glScissor uses window coordinates, not viewport coordinates,
04817      * so our viewport correction does not apply. Warning2: Even in windowed
04818      * mode the coords are relative to the window, not the screen. */
04819     TRACE("Setting new scissor rect to %s.\n", wine_dbgstr_rect(r));
04820 
04821     if (context->render_offscreen)
04822     {
04823         glScissor(r->left, r->top, r->right - r->left, r->bottom - r->top);
04824     }
04825     else
04826     {
04827         const struct wined3d_surface *target = state->fb->render_targets[0];
04828         UINT height;
04829         UINT width;
04830 
04831         target->get_drawable_size(context, &width, &height);
04832         glScissor(r->left, height - r->bottom, r->right - r->left, r->bottom - r->top);
04833     }
04834     checkGLcall("glScissor");
04835 }
04836 
04837 static void indexbuffer(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04838 {
04839     const struct wined3d_gl_info *gl_info = context->gl_info;
04840 
04841     if (state->user_stream || !state->index_buffer)
04842     {
04843         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
04844     }
04845     else
04846     {
04847         struct wined3d_buffer *ib = state->index_buffer;
04848         GL_EXTCALL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ib->buffer_object));
04849     }
04850 }
04851 
04852 static void frontface(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04853 {
04854     if (context->render_offscreen)
04855     {
04856         glFrontFace(GL_CCW);
04857         checkGLcall("glFrontFace(GL_CCW)");
04858     } else {
04859         glFrontFace(GL_CW);
04860         checkGLcall("glFrontFace(GL_CW)");
04861     }
04862 }
04863 
04864 static void psorigin_w(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04865 {
04866     static BOOL warned;
04867 
04868     if (!warned)
04869     {
04870         WARN("Point sprite coordinate origin switching not supported.\n");
04871         warned = TRUE;
04872     }
04873 }
04874 
04875 static void psorigin(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
04876 {
04877     const struct wined3d_gl_info *gl_info = context->gl_info;
04878     GLint origin = context->render_offscreen ? GL_LOWER_LEFT : GL_UPPER_LEFT;
04879 
04880     if (glPointParameteri)
04881     {
04882         glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, origin);
04883         checkGLcall("glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
04884     }
04885     else if (gl_info->supported[NV_POINT_SPRITE])
04886     {
04887         GL_EXTCALL(glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, origin));
04888         checkGLcall("glPointParameteriNV(GL_POINT_SPRITE_COORD_ORIGIN, ...)");
04889     }
04890 }
04891 
04892 const struct StateEntryTemplate misc_state_template[] = {
04893     { STATE_RENDER(WINED3D_RS_SRCBLEND),                  { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
04894     { STATE_RENDER(WINED3D_RS_DESTBLEND),                 { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
04895     { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          state_blend         }, WINED3D_GL_EXT_NONE             },
04896     { STATE_RENDER(WINED3D_RS_EDGEANTIALIAS),             { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
04897     { STATE_RENDER(WINED3D_RS_ANTIALIASEDLINEENABLE),     { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
04898     { STATE_RENDER(WINED3D_RS_SEPARATEALPHABLENDENABLE),  { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
04899     { STATE_RENDER(WINED3D_RS_SRCBLENDALPHA),             { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
04900     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
04901     { STATE_RENDER(WINED3D_RS_DESTBLENDALPHA),            { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
04902     { STATE_RENDER(WINED3D_RS_BLENDOPALPHA),              { STATE_RENDER(WINED3D_RS_ALPHABLENDENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
04903     { STATE_STREAMSRC,                                    { STATE_STREAMSRC,                                    streamsrc           }, WINED3D_GL_EXT_NONE             },
04904     { STATE_VDECL,                                        { STATE_VDECL,                                        vdecl_miscpart      }, WINED3D_GL_EXT_NONE             },
04905     { STATE_FRONTFACE,                                    { STATE_FRONTFACE,                                    frontface           }, WINED3D_GL_EXT_NONE             },
04906     { STATE_SCISSORRECT,                                  { STATE_SCISSORRECT,                                  scissorrect         }, WINED3D_GL_EXT_NONE             },
04907     { STATE_POINTSPRITECOORDORIGIN,                       { STATE_POINTSPRITECOORDORIGIN,                       psorigin            }, WINED3D_GL_VERSION_2_0          },
04908     { STATE_POINTSPRITECOORDORIGIN,                       { STATE_POINTSPRITECOORDORIGIN,                       psorigin_w          }, WINED3D_GL_EXT_NONE             },
04909 
04910     /* TODO: Move shader constant loading to vertex and fragment pipeline respectively, as soon as the pshader and
04911      * vshader loadings are untied from each other
04912      */
04913     { STATE_VERTEXSHADERCONSTANT,                         { STATE_VERTEXSHADERCONSTANT,                         shaderconstant      }, WINED3D_GL_EXT_NONE             },
04914     { STATE_PIXELSHADERCONSTANT,                          { STATE_VERTEXSHADERCONSTANT,                         NULL                }, WINED3D_GL_EXT_NONE             },
04915     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
04916     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04917     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04918     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04919     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
04920     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04921     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04922     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04923     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
04924     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04925     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04926     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04927     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
04928     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04929     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04930     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04931     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
04932     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04933     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04934     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04935     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
04936     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04937     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04938     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04939     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
04940     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04941     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04942     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04943     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   shader_bumpenvmat   }, WINED3D_GL_EXT_NONE             },
04944     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT01),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04945     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT10),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04946     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT11),   { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_MAT00),   NULL                }, WINED3D_GL_EXT_NONE             },
04947     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
04948     { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(0, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
04949     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
04950     { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(1, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
04951     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
04952     { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(2, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
04953     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
04954     { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(3, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
04955     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
04956     { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(4, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
04957     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
04958     { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(5, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
04959     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
04960     { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(6, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
04961     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE),  { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE),  tex_bumpenvlscale   }, WINED3D_GL_EXT_NONE             },
04962     { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LOFFSET), { STATE_TEXTURESTAGE(7, WINED3D_TSS_BUMPENV_LSCALE),  NULL                }, WINED3D_GL_EXT_NONE             },
04963 
04964     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_miscpart   }, WINED3D_GL_EXT_NONE             },
04965     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  indexbuffer         }, ARB_VERTEX_BUFFER_OBJECT        },
04966     { STATE_INDEXBUFFER,                                  { STATE_INDEXBUFFER,                                  state_nop           }, WINED3D_GL_EXT_NONE             },
04967     { STATE_RENDER(WINED3D_RS_ANTIALIAS),                 { STATE_RENDER(WINED3D_RS_ANTIALIAS),                 state_antialias     }, WINED3D_GL_EXT_NONE             },
04968     { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE),        { STATE_RENDER(WINED3D_RS_TEXTUREPERSPECTIVE),        state_perspective   }, WINED3D_GL_EXT_NONE             },
04969     { STATE_RENDER(WINED3D_RS_ZENABLE),                   { STATE_RENDER(WINED3D_RS_ZENABLE),                   state_zenable       }, WINED3D_GL_EXT_NONE             },
04970     { STATE_RENDER(WINED3D_RS_WRAPU),                     { STATE_RENDER(WINED3D_RS_WRAPU),                     state_wrapu         }, WINED3D_GL_EXT_NONE             },
04971     { STATE_RENDER(WINED3D_RS_WRAPV),                     { STATE_RENDER(WINED3D_RS_WRAPV),                     state_wrapv         }, WINED3D_GL_EXT_NONE             },
04972     { STATE_RENDER(WINED3D_RS_FILLMODE),                  { STATE_RENDER(WINED3D_RS_FILLMODE),                  state_fillmode      }, WINED3D_GL_EXT_NONE             },
04973     { STATE_RENDER(WINED3D_RS_SHADEMODE),                 { STATE_RENDER(WINED3D_RS_SHADEMODE),                 state_shademode     }, WINED3D_GL_EXT_NONE             },
04974     { STATE_RENDER(WINED3D_RS_LINEPATTERN),               { STATE_RENDER(WINED3D_RS_LINEPATTERN),               state_linepattern   }, WINED3D_GL_EXT_NONE             },
04975     { STATE_RENDER(WINED3D_RS_MONOENABLE),                { STATE_RENDER(WINED3D_RS_MONOENABLE),                state_monoenable    }, WINED3D_GL_EXT_NONE             },
04976     { STATE_RENDER(WINED3D_RS_ROP2),                      { STATE_RENDER(WINED3D_RS_ROP2),                      state_rop2          }, WINED3D_GL_EXT_NONE             },
04977     { STATE_RENDER(WINED3D_RS_PLANEMASK),                 { STATE_RENDER(WINED3D_RS_PLANEMASK),                 state_planemask     }, WINED3D_GL_EXT_NONE             },
04978     { STATE_RENDER(WINED3D_RS_ZWRITEENABLE),              { STATE_RENDER(WINED3D_RS_ZWRITEENABLE),              state_zwritenable   }, WINED3D_GL_EXT_NONE             },
04979     { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           state_alpha         }, WINED3D_GL_EXT_NONE             },
04980     { STATE_RENDER(WINED3D_RS_ALPHAREF),                  { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
04981     { STATE_RENDER(WINED3D_RS_ALPHAFUNC),                 { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
04982     { STATE_RENDER(WINED3D_RS_COLORKEYENABLE),            { STATE_RENDER(WINED3D_RS_ALPHATESTENABLE),           NULL                }, WINED3D_GL_EXT_NONE             },
04983     { STATE_RENDER(WINED3D_RS_LASTPIXEL),                 { STATE_RENDER(WINED3D_RS_LASTPIXEL),                 state_lastpixel     }, WINED3D_GL_EXT_NONE             },
04984     { STATE_RENDER(WINED3D_RS_CULLMODE),                  { STATE_RENDER(WINED3D_RS_CULLMODE),                  state_cullmode      }, WINED3D_GL_EXT_NONE             },
04985     { STATE_RENDER(WINED3D_RS_ZFUNC),                     { STATE_RENDER(WINED3D_RS_ZFUNC),                     state_zfunc         }, WINED3D_GL_EXT_NONE             },
04986     { STATE_RENDER(WINED3D_RS_DITHERENABLE),              { STATE_RENDER(WINED3D_RS_DITHERENABLE),              state_ditherenable  }, WINED3D_GL_EXT_NONE             },
04987     { STATE_RENDER(WINED3D_RS_SUBPIXEL),                  { STATE_RENDER(WINED3D_RS_SUBPIXEL),                  state_subpixel      }, WINED3D_GL_EXT_NONE             },
04988     { STATE_RENDER(WINED3D_RS_SUBPIXELX),                 { STATE_RENDER(WINED3D_RS_SUBPIXELX),                 state_subpixelx     }, WINED3D_GL_EXT_NONE             },
04989     { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA),             { STATE_RENDER(WINED3D_RS_STIPPLEDALPHA),             state_stippledalpha }, WINED3D_GL_EXT_NONE             },
04990     { STATE_RENDER(WINED3D_RS_STIPPLEENABLE),             { STATE_RENDER(WINED3D_RS_STIPPLEENABLE),             state_stippleenable }, WINED3D_GL_EXT_NONE             },
04991     { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS),             { STATE_RENDER(WINED3D_RS_MIPMAPLODBIAS),             state_mipmaplodbias }, WINED3D_GL_EXT_NONE             },
04992     { STATE_RENDER(WINED3D_RS_ANISOTROPY),                { STATE_RENDER(WINED3D_RS_ANISOTROPY),                state_anisotropy    }, WINED3D_GL_EXT_NONE             },
04993     { STATE_RENDER(WINED3D_RS_FLUSHBATCH),                { STATE_RENDER(WINED3D_RS_FLUSHBATCH),                state_flushbatch    }, WINED3D_GL_EXT_NONE             },
04994     { STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),{ STATE_RENDER(WINED3D_RS_TRANSLUCENTSORTINDEPENDENT),state_translucentsi }, WINED3D_GL_EXT_NONE             },
04995     { STATE_RENDER(WINED3D_RS_STENCILENABLE),             { STATE_RENDER(WINED3D_RS_STENCILENABLE),             state_stencil       }, WINED3D_GL_EXT_NONE             },
04996     { STATE_RENDER(WINED3D_RS_STENCILFAIL),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
04997     { STATE_RENDER(WINED3D_RS_STENCILZFAIL),              { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
04998     { STATE_RENDER(WINED3D_RS_STENCILPASS),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
04999     { STATE_RENDER(WINED3D_RS_STENCILFUNC),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
05000     { STATE_RENDER(WINED3D_RS_STENCILREF),                { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
05001     { STATE_RENDER(WINED3D_RS_STENCILMASK),               { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
05002     { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          state_stencilwrite2s}, EXT_STENCIL_TWO_SIDE            },
05003     { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          { STATE_RENDER(WINED3D_RS_STENCILWRITEMASK),          state_stencilwrite  }, WINED3D_GL_EXT_NONE             },
05004     { STATE_RENDER(WINED3D_RS_TWOSIDEDSTENCILMODE),       { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
05005     { STATE_RENDER(WINED3D_RS_CCW_STENCILFAIL),           { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
05006     { STATE_RENDER(WINED3D_RS_CCW_STENCILZFAIL),          { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
05007     { STATE_RENDER(WINED3D_RS_CCW_STENCILPASS),           { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
05008     { STATE_RENDER(WINED3D_RS_CCW_STENCILFUNC),           { STATE_RENDER(WINED3D_RS_STENCILENABLE),             NULL                }, WINED3D_GL_EXT_NONE             },
05009     { STATE_RENDER(WINED3D_RS_WRAP0),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     state_wrap          }, WINED3D_GL_EXT_NONE             },
05010     { STATE_RENDER(WINED3D_RS_WRAP1),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05011     { STATE_RENDER(WINED3D_RS_WRAP2),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05012     { STATE_RENDER(WINED3D_RS_WRAP3),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05013     { STATE_RENDER(WINED3D_RS_WRAP4),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05014     { STATE_RENDER(WINED3D_RS_WRAP5),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05015     { STATE_RENDER(WINED3D_RS_WRAP6),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05016     { STATE_RENDER(WINED3D_RS_WRAP7),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05017     { STATE_RENDER(WINED3D_RS_WRAP8),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05018     { STATE_RENDER(WINED3D_RS_WRAP9),                     { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05019     { STATE_RENDER(WINED3D_RS_WRAP10),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05020     { STATE_RENDER(WINED3D_RS_WRAP11),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05021     { STATE_RENDER(WINED3D_RS_WRAP12),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05022     { STATE_RENDER(WINED3D_RS_WRAP13),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05023     { STATE_RENDER(WINED3D_RS_WRAP14),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05024     { STATE_RENDER(WINED3D_RS_WRAP15),                    { STATE_RENDER(WINED3D_RS_WRAP0),                     NULL                }, WINED3D_GL_EXT_NONE             },
05025     { STATE_RENDER(WINED3D_RS_EXTENTS),                   { STATE_RENDER(WINED3D_RS_EXTENTS),                   state_extents       }, WINED3D_GL_EXT_NONE             },
05026     { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE),       { STATE_RENDER(WINED3D_RS_COLORKEYBLENDENABLE),       state_ckeyblend     }, WINED3D_GL_EXT_NONE             },
05027     { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING),  { STATE_RENDER(WINED3D_RS_SOFTWAREVERTEXPROCESSING),  state_swvp          }, WINED3D_GL_EXT_NONE             },
05028     { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE),            { STATE_RENDER(WINED3D_RS_PATCHEDGESTYLE),            state_patchedgestyle}, WINED3D_GL_EXT_NONE             },
05029     { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS),             { STATE_RENDER(WINED3D_RS_PATCHSEGMENTS),             state_patchsegments }, WINED3D_GL_EXT_NONE             },
05030     { STATE_RENDER(WINED3D_RS_POSITIONDEGREE),            { STATE_RENDER(WINED3D_RS_POSITIONDEGREE),            state_positiondegree}, WINED3D_GL_EXT_NONE             },
05031     { STATE_RENDER(WINED3D_RS_NORMALDEGREE),              { STATE_RENDER(WINED3D_RS_NORMALDEGREE),              state_normaldegree  }, WINED3D_GL_EXT_NONE             },
05032     { STATE_RENDER(WINED3D_RS_MINTESSELLATIONLEVEL),      { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
05033     { STATE_RENDER(WINED3D_RS_MAXTESSELLATIONLEVEL),      { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
05034     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_X),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
05035     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Y),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
05036     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_Z),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
05037     { STATE_RENDER(WINED3D_RS_ADAPTIVETESS_W),            { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),NULL                }, WINED3D_GL_EXT_NONE             },
05038     { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_nvdb          }, EXT_DEPTH_BOUNDS_TEST           },
05039     { STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),{ STATE_RENDER(WINED3D_RS_ENABLEADAPTIVETESSELLATION),state_tessellation  }, WINED3D_GL_EXT_NONE             },
05040     { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      state_msaa          }, ARB_MULTISAMPLE                 },
05041     { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      { STATE_RENDER(WINED3D_RS_MULTISAMPLEANTIALIAS),      state_msaa_w        }, WINED3D_GL_EXT_NONE             },
05042     { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           { STATE_RENDER(WINED3D_RS_MULTISAMPLEMASK),           state_multisampmask }, WINED3D_GL_EXT_NONE             },
05043     { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         { STATE_RENDER(WINED3D_RS_DEBUGMONITORTOKEN),         state_debug_monitor }, WINED3D_GL_EXT_NONE             },
05044     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite0   }, EXT_DRAW_BUFFERS2               },
05045     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          state_colorwrite    }, WINED3D_GL_EXT_NONE             },
05046     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop       }, EXT_BLEND_MINMAX                },
05047     { STATE_RENDER(WINED3D_RS_BLENDOP),                   { STATE_RENDER(WINED3D_RS_BLENDOP),                   state_blendop_w     }, WINED3D_GL_EXT_NONE             },
05048     { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         { STATE_RENDER(WINED3D_RS_SCISSORTESTENABLE),         state_scissor       }, WINED3D_GL_EXT_NONE             },
05049     { STATE_RENDER(WINED3D_RS_SLOPESCALEDEPTHBIAS),       { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 NULL                }, WINED3D_GL_EXT_NONE             },
05050     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         state_colorwrite1   }, EXT_DRAW_BUFFERS2               },
05051     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE1),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
05052     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         state_colorwrite2   }, EXT_DRAW_BUFFERS2               },
05053     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE2),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
05054     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         state_colorwrite3   }, EXT_DRAW_BUFFERS2               },
05055     { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE3),         { STATE_RENDER(WINED3D_RS_COLORWRITEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
05056     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor   }, EXT_BLEND_COLOR                 },
05057     { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               { STATE_RENDER(WINED3D_RS_BLENDFACTOR),               state_blendfactor_w }, WINED3D_GL_EXT_NONE             },
05058     { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 { STATE_RENDER(WINED3D_RS_DEPTHBIAS),                 state_depthbias     }, WINED3D_GL_EXT_NONE             },
05059     { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  { STATE_RENDER(WINED3D_RS_ZVISIBLE),                  state_zvisible      }, WINED3D_GL_EXT_NONE             },
05060     /* Samplers */
05061     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05062     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05063     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05064     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05065     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05066     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05067     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05068     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05069     { STATE_SAMPLER(8),                                   { STATE_SAMPLER(8),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05070     { STATE_SAMPLER(9),                                   { STATE_SAMPLER(9),                                   sampler             }, WINED3D_GL_EXT_NONE             },
05071     { STATE_SAMPLER(10),                                  { STATE_SAMPLER(10),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05072     { STATE_SAMPLER(11),                                  { STATE_SAMPLER(11),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05073     { STATE_SAMPLER(12),                                  { STATE_SAMPLER(12),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05074     { STATE_SAMPLER(13),                                  { STATE_SAMPLER(13),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05075     { STATE_SAMPLER(14),                                  { STATE_SAMPLER(14),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05076     { STATE_SAMPLER(15),                                  { STATE_SAMPLER(15),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05077     { STATE_SAMPLER(16), /* Vertex sampler 0 */           { STATE_SAMPLER(16),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05078     { STATE_SAMPLER(17), /* Vertex sampler 1 */           { STATE_SAMPLER(17),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05079     { STATE_SAMPLER(18), /* Vertex sampler 2 */           { STATE_SAMPLER(18),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05080     { STATE_SAMPLER(19), /* Vertex sampler 3 */           { STATE_SAMPLER(19),                                  sampler             }, WINED3D_GL_EXT_NONE             },
05081     { STATE_BASEVERTEXINDEX,                              { STATE_BASEVERTEXINDEX,                              state_nop,          }, ARB_DRAW_ELEMENTS_BASE_VERTEX   },
05082     { STATE_BASEVERTEXINDEX,                              { STATE_STREAMSRC,                                    NULL,               }, WINED3D_GL_EXT_NONE             },
05083     { STATE_FRAMEBUFFER,                                  { STATE_FRAMEBUFFER,                                  context_state_fb    }, WINED3D_GL_EXT_NONE             },
05084     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  context_state_drawbuf},WINED3D_GL_EXT_NONE             },
05085     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
05086 };
05087 
05088 const struct StateEntryTemplate ffp_vertexstate_template[] = {
05089     { STATE_VDECL,                                        { STATE_VDECL,                                        vertexdeclaration   }, WINED3D_GL_EXT_NONE             },
05090     { STATE_VSHADER,                                      { STATE_VDECL,                                        NULL                }, WINED3D_GL_EXT_NONE             },
05091     { STATE_MATERIAL,                                     { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            NULL                }, WINED3D_GL_EXT_NONE             },
05092     { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            { STATE_RENDER(WINED3D_RS_SPECULARENABLE),            state_specularenable}, WINED3D_GL_EXT_NONE             },
05093       /* Clip planes */
05094     { STATE_CLIPPLANE(0),                                 { STATE_CLIPPLANE(0),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05095     { STATE_CLIPPLANE(1),                                 { STATE_CLIPPLANE(1),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05096     { STATE_CLIPPLANE(2),                                 { STATE_CLIPPLANE(2),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05097     { STATE_CLIPPLANE(3),                                 { STATE_CLIPPLANE(3),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05098     { STATE_CLIPPLANE(4),                                 { STATE_CLIPPLANE(4),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05099     { STATE_CLIPPLANE(5),                                 { STATE_CLIPPLANE(5),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05100     { STATE_CLIPPLANE(6),                                 { STATE_CLIPPLANE(6),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05101     { STATE_CLIPPLANE(7),                                 { STATE_CLIPPLANE(7),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05102     { STATE_CLIPPLANE(8),                                 { STATE_CLIPPLANE(8),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05103     { STATE_CLIPPLANE(9),                                 { STATE_CLIPPLANE(9),                                 clipplane           }, WINED3D_GL_EXT_NONE             },
05104     { STATE_CLIPPLANE(10),                                { STATE_CLIPPLANE(10),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05105     { STATE_CLIPPLANE(11),                                { STATE_CLIPPLANE(11),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05106     { STATE_CLIPPLANE(12),                                { STATE_CLIPPLANE(12),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05107     { STATE_CLIPPLANE(13),                                { STATE_CLIPPLANE(13),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05108     { STATE_CLIPPLANE(14),                                { STATE_CLIPPLANE(14),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05109     { STATE_CLIPPLANE(15),                                { STATE_CLIPPLANE(15),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05110     { STATE_CLIPPLANE(16),                                { STATE_CLIPPLANE(16),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05111     { STATE_CLIPPLANE(17),                                { STATE_CLIPPLANE(17),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05112     { STATE_CLIPPLANE(18),                                { STATE_CLIPPLANE(18),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05113     { STATE_CLIPPLANE(19),                                { STATE_CLIPPLANE(19),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05114     { STATE_CLIPPLANE(20),                                { STATE_CLIPPLANE(20),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05115     { STATE_CLIPPLANE(21),                                { STATE_CLIPPLANE(21),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05116     { STATE_CLIPPLANE(22),                                { STATE_CLIPPLANE(22),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05117     { STATE_CLIPPLANE(23),                                { STATE_CLIPPLANE(23),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05118     { STATE_CLIPPLANE(24),                                { STATE_CLIPPLANE(24),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05119     { STATE_CLIPPLANE(25),                                { STATE_CLIPPLANE(25),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05120     { STATE_CLIPPLANE(26),                                { STATE_CLIPPLANE(26),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05121     { STATE_CLIPPLANE(27),                                { STATE_CLIPPLANE(27),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05122     { STATE_CLIPPLANE(28),                                { STATE_CLIPPLANE(28),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05123     { STATE_CLIPPLANE(29),                                { STATE_CLIPPLANE(29),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05124     { STATE_CLIPPLANE(30),                                { STATE_CLIPPLANE(30),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05125     { STATE_CLIPPLANE(31),                                { STATE_CLIPPLANE(31),                                clipplane           }, WINED3D_GL_EXT_NONE             },
05126       /* Lights */
05127     { STATE_ACTIVELIGHT(0),                               { STATE_ACTIVELIGHT(0),                               light               }, WINED3D_GL_EXT_NONE             },
05128     { STATE_ACTIVELIGHT(1),                               { STATE_ACTIVELIGHT(1),                               light               }, WINED3D_GL_EXT_NONE             },
05129     { STATE_ACTIVELIGHT(2),                               { STATE_ACTIVELIGHT(2),                               light               }, WINED3D_GL_EXT_NONE             },
05130     { STATE_ACTIVELIGHT(3),                               { STATE_ACTIVELIGHT(3),                               light               }, WINED3D_GL_EXT_NONE             },
05131     { STATE_ACTIVELIGHT(4),                               { STATE_ACTIVELIGHT(4),                               light               }, WINED3D_GL_EXT_NONE             },
05132     { STATE_ACTIVELIGHT(5),                               { STATE_ACTIVELIGHT(5),                               light               }, WINED3D_GL_EXT_NONE             },
05133     { STATE_ACTIVELIGHT(6),                               { STATE_ACTIVELIGHT(6),                               light               }, WINED3D_GL_EXT_NONE             },
05134     { STATE_ACTIVELIGHT(7),                               { STATE_ACTIVELIGHT(7),                               light               }, WINED3D_GL_EXT_NONE             },
05135     /* Viewport */
05136     { STATE_VIEWPORT,                                     { STATE_VIEWPORT,                                     viewport_vertexpart }, WINED3D_GL_EXT_NONE             },
05137       /* Transform states follow                    */
05138     { STATE_TRANSFORM(WINED3D_TS_VIEW),                   { STATE_TRANSFORM(WINED3D_TS_VIEW),                   transform_view      }, WINED3D_GL_EXT_NONE             },
05139     { STATE_TRANSFORM(WINED3D_TS_PROJECTION),             { STATE_TRANSFORM(WINED3D_TS_PROJECTION),             transform_projection}, WINED3D_GL_EXT_NONE             },
05140     { STATE_TRANSFORM(WINED3D_TS_TEXTURE0),               { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
05141     { STATE_TRANSFORM(WINED3D_TS_TEXTURE1),               { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
05142     { STATE_TRANSFORM(WINED3D_TS_TEXTURE2),               { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
05143     { STATE_TRANSFORM(WINED3D_TS_TEXTURE3),               { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
05144     { STATE_TRANSFORM(WINED3D_TS_TEXTURE4),               { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
05145     { STATE_TRANSFORM(WINED3D_TS_TEXTURE5),               { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
05146     { STATE_TRANSFORM(WINED3D_TS_TEXTURE6),               { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
05147     { STATE_TRANSFORM(WINED3D_TS_TEXTURE7),               { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL            }, WINED3D_GL_EXT_NONE             },
05148     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  0)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  0)),      transform_world     }, WINED3D_GL_EXT_NONE             },
05149     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  1)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  1)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05150     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  2)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  2)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05151     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  3)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  3)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05152     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  4)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  4)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05153     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  5)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  5)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05154     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  6)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  6)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05155     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  7)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  7)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05156     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  8)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  8)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05157     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  9)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(  9)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05158     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 10)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05159     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 11)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05160     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 12)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05161     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 13)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05162     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 14)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05163     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 15)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05164     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 16)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05165     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 17)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05166     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 18)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05167     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 19)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05168     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 20)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05169     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 21)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05170     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 22)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05171     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 23)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05172     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 24)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05173     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 25)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05174     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 26)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05175     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 27)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05176     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 28)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05177     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 29)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05178     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 30)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05179     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 31)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05180     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 32)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05181     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 33)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05182     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 34)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05183     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 35)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05184     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 36)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05185     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 37)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05186     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 38)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05187     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 39)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05188     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 40)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05189     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 41)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05190     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 42)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05191     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 43)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05192     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 44)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05193     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 45)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05194     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 46)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05195     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 47)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05196     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 48)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05197     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 49)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05198     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 50)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05199     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 51)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05200     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 52)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05201     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 53)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05202     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 54)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05203     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 55)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05204     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 56)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05205     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 57)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05206     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 58)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05207     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 59)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05208     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 60)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05209     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 61)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05210     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 62)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05211     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 63)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05212     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 64)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05213     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 65)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05214     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 66)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05215     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 67)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05216     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 68)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05217     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 69)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05218     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 70)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05219     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 71)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05220     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 72)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05221     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 73)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05222     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 74)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05223     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 75)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05224     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 76)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05225     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 77)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05226     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 78)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05227     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 79)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05228     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 80)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05229     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 81)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05230     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 82)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05231     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 83)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05232     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 84)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05233     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 85)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05234     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 86)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05235     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 87)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05236     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 88)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05237     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 89)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05238     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 90)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05239     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 91)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05240     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 92)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05241     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 93)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05242     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 94)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05243     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 95)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05244     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 96)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05245     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 97)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05246     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 98)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05247     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX( 99)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05248     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(100)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05249     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(101)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05250     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(102)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05251     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(103)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05252     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(104)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05253     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(105)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05254     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(106)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05255     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(107)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05256     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(108)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05257     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(109)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05258     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(110)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05259     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(111)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05260     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(112)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05261     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(113)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05262     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(114)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05263     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(115)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05264     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(116)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05265     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(117)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05266     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(118)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05267     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(119)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05268     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(120)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05269     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(121)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05270     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(122)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05271     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(123)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05272     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(124)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05273     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(125)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05274     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(126)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05275     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(127)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05276     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(128)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05277     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(129)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05278     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(130)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05279     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(131)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05280     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(132)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05281     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(133)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05282     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(134)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05283     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(135)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05284     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(136)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05285     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(137)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05286     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(138)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05287     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(139)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05288     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(140)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05289     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(141)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05290     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(142)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05291     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(143)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05292     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(144)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05293     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(145)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05294     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(146)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05295     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(147)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05296     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(148)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05297     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(149)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05298     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(150)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05299     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(151)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05300     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(152)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05301     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(153)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05302     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(154)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05303     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(155)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05304     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(156)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05305     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(157)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05306     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(158)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05307     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(159)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05308     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(160)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05309     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(161)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05310     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(162)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05311     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(163)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05312     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(164)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05313     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(165)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05314     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(166)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05315     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(167)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05316     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(168)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05317     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(169)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05318     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(170)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05319     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(171)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05320     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(172)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05321     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(173)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05322     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(174)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05323     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(175)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05324     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(176)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05325     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(177)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05326     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(178)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05327     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(179)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05328     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(180)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05329     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(181)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05330     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(182)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05331     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(183)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05332     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(184)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05333     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(185)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05334     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(186)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05335     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(187)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05336     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(188)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05337     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(189)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05338     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(190)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05339     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(191)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05340     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(192)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05341     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(193)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05342     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(194)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05343     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(195)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05344     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(196)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05345     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(197)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05346     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(198)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05347     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(199)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05348     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(200)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05349     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(201)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05350     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(202)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05351     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(203)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05352     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(204)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05353     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(205)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05354     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(206)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05355     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(207)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05356     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(208)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05357     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(209)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05358     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(210)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05359     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(211)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05360     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(212)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05361     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(213)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05362     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(214)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05363     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(215)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05364     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(216)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05365     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(217)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05366     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(218)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05367     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(219)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05368     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(220)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05369     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(221)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05370     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(222)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05371     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(223)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05372     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(224)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05373     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(225)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05374     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(226)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05375     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(227)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05376     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(228)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05377     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(229)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05378     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(230)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05379     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(231)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05380     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(232)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05381     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(233)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05382     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(234)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05383     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(235)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05384     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(236)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05385     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(237)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05386     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(238)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05387     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(239)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05388     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(240)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05389     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(241)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05390     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(242)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05391     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(243)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05392     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(244)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05393     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(245)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05394     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(246)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05395     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(247)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05396     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(248)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05397     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(249)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05398     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(250)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05399     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(251)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05400     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(252)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05401     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(253)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05402     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(254)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05403     { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)),      { STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255)),      transform_worldex   }, WINED3D_GL_EXT_NONE             },
05404     { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
05405     { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
05406     { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
05407     { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
05408     { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
05409     { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
05410     { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
05411     { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture   }, WINED3D_GL_EXT_NONE             },
05412     { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
05413     { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
05414     { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
05415     { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
05416     { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
05417     { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
05418     { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
05419     { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX),  { STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXCOORD_INDEX),  tex_coordindex      }, WINED3D_GL_EXT_NONE             },
05420       /* Fog */
05421     { STATE_RENDER(WINED3D_RS_FOGENABLE),                 { STATE_RENDER(WINED3D_RS_FOGENABLE),                 state_fog_vertexpart}, WINED3D_GL_EXT_NONE             },
05422     { STATE_RENDER(WINED3D_RS_FOGTABLEMODE),              { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
05423     { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE),             { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
05424     { STATE_RENDER(WINED3D_RS_RANGEFOGENABLE),            { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
05425     { STATE_RENDER(WINED3D_RS_CLIPPING),                  { STATE_RENDER(WINED3D_RS_CLIPPING),                  state_clipping      }, WINED3D_GL_EXT_NONE             },
05426     { STATE_RENDER(WINED3D_RS_CLIPPLANEENABLE),           { STATE_RENDER(WINED3D_RS_CLIPPING),                  NULL                }, WINED3D_GL_EXT_NONE             },
05427     { STATE_RENDER(WINED3D_RS_LIGHTING),                  { STATE_RENDER(WINED3D_RS_LIGHTING),                  state_lighting      }, WINED3D_GL_EXT_NONE             },
05428     { STATE_RENDER(WINED3D_RS_AMBIENT),                   { STATE_RENDER(WINED3D_RS_AMBIENT),                   state_ambient       }, WINED3D_GL_EXT_NONE             },
05429     { STATE_RENDER(WINED3D_RS_COLORVERTEX),               { STATE_RENDER(WINED3D_RS_COLORVERTEX),               state_colormat      }, WINED3D_GL_EXT_NONE             },
05430     { STATE_RENDER(WINED3D_RS_LOCALVIEWER),               { STATE_RENDER(WINED3D_RS_LOCALVIEWER),               state_localviewer   }, WINED3D_GL_EXT_NONE             },
05431     { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS),          { STATE_RENDER(WINED3D_RS_NORMALIZENORMALS),          state_normalize     }, WINED3D_GL_EXT_NONE             },
05432     { STATE_RENDER(WINED3D_RS_DIFFUSEMATERIALSOURCE),     { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
05433     { STATE_RENDER(WINED3D_RS_SPECULARMATERIALSOURCE),    { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
05434     { STATE_RENDER(WINED3D_RS_AMBIENTMATERIALSOURCE),     { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
05435     { STATE_RENDER(WINED3D_RS_EMISSIVEMATERIALSOURCE),    { STATE_RENDER(WINED3D_RS_COLORVERTEX),               NULL                }, WINED3D_GL_EXT_NONE             },
05436     { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               state_vertexblend   }, ARB_VERTEX_BLEND                },
05437     { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               state_vertexblend_w }, WINED3D_GL_EXT_NONE             },
05438     { STATE_RENDER(WINED3D_RS_POINTSIZE),                 { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
05439     { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             state_psizemin_arb  }, ARB_POINT_PARAMETERS            },
05440     { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             state_psizemin_ext  }, EXT_POINT_PARAMETERS            },
05441     { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             state_psizemin_w    }, WINED3D_GL_EXT_NONE             },
05442     { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         state_pointsprite   }, ARB_POINT_SPRITE                },
05443     { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         { STATE_RENDER(WINED3D_RS_POINTSPRITEENABLE),         state_pointsprite_w }, WINED3D_GL_EXT_NONE             },
05444     { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          state_pscale        }, WINED3D_GL_EXT_NONE             },
05445     { STATE_RENDER(WINED3D_RS_POINTSCALE_A),              { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
05446     { STATE_RENDER(WINED3D_RS_POINTSCALE_B),              { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
05447     { STATE_RENDER(WINED3D_RS_POINTSCALE_C),              { STATE_RENDER(WINED3D_RS_POINTSCALEENABLE),          NULL                }, WINED3D_GL_EXT_NONE             },
05448     { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             NULL                }, ARB_POINT_PARAMETERS            },
05449     { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             NULL                }, EXT_POINT_PARAMETERS            },
05450     { STATE_RENDER(WINED3D_RS_POINTSIZE_MAX),             { STATE_RENDER(WINED3D_RS_POINTSIZE_MIN),             NULL                }, WINED3D_GL_EXT_NONE             },
05451     { STATE_RENDER(WINED3D_RS_TWEENFACTOR),               { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               NULL                }, WINED3D_GL_EXT_NONE             },
05452     { STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE),  { STATE_RENDER(WINED3D_RS_VERTEXBLEND),               NULL                }, WINED3D_GL_EXT_NONE             },
05453 
05454     /* Samplers for NP2 texture matrix adjustions. They are not needed if GL_ARB_texture_non_power_of_two is supported,
05455      * so register a NULL state handler in that case to get the vertex part of sampler() skipped(VTF is handled in the misc states.
05456      * otherwise, register sampler_texmatrix, which takes care of updating the texture matrix
05457      */
05458     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
05459     { STATE_SAMPLER(0),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
05460     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
05461     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
05462     { STATE_SAMPLER(1),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
05463     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
05464     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
05465     { STATE_SAMPLER(2),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
05466     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
05467     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
05468     { STATE_SAMPLER(3),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
05469     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
05470     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
05471     { STATE_SAMPLER(4),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
05472     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
05473     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
05474     { STATE_SAMPLER(5),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
05475     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
05476     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
05477     { STATE_SAMPLER(6),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
05478     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
05479     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, ARB_TEXTURE_NON_POWER_OF_TWO    },
05480     { STATE_SAMPLER(7),                                   { 0,                                                  NULL                }, WINED3D_GL_NORMALIZED_TEXRECT   },
05481     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texmatrix   }, WINED3D_GL_EXT_NONE             },
05482     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
05483 };
05484 
05485 static const struct StateEntryTemplate ffp_fragmentstate_template[] = {
05486     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
05487     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05488     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05489     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
05490     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05491     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05492     { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05493     { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05494     { STATE_TEXTURESTAGE(0, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(0, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05495     { STATE_TEXTURESTAGE(0, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
05496     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
05497     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05498     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05499     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
05500     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05501     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05502     { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05503     { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05504     { STATE_TEXTURESTAGE(1, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(1, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05505     { STATE_TEXTURESTAGE(1, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
05506     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
05507     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05508     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05509     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
05510     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05511     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05512     { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05513     { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05514     { STATE_TEXTURESTAGE(2, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(2, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05515     { STATE_TEXTURESTAGE(2, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
05516     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
05517     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05518     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05519     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
05520     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05521     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05522     { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05523     { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05524     { STATE_TEXTURESTAGE(3, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(3, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05525     { STATE_TEXTURESTAGE(3, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
05526     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
05527     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05528     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05529     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
05530     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05531     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05532     { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05533     { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05534     { STATE_TEXTURESTAGE(4, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(4, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05535     { STATE_TEXTURESTAGE(4, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
05536     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
05537     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05538     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05539     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
05540     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05541     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05542     { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05543     { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05544     { STATE_TEXTURESTAGE(5, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(5, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05545     { STATE_TEXTURESTAGE(5, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
05546     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
05547     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05548     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05549     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
05550     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05551     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05552     { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05553     { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05554     { STATE_TEXTURESTAGE(6, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(6, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05555     { STATE_TEXTURESTAGE(6, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
05556     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        tex_colorop         }, WINED3D_GL_EXT_NONE             },
05557     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG1),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05558     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG2),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05559     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        tex_alphaop         }, WINED3D_GL_EXT_NONE             },
05560     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG1),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05561     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG2),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05562     { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_ARG0),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05563     { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_ARG0),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_ALPHA_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05564     { STATE_TEXTURESTAGE(7, WINED3D_TSS_RESULT_ARG),      { STATE_TEXTURESTAGE(7, WINED3D_TSS_COLOR_OP),        NULL                }, WINED3D_GL_EXT_NONE             },
05565     { STATE_TEXTURESTAGE(7, WINED3D_TSS_CONSTANT),        { 0 /* As long as we don't support D3DTA_CONSTANT */, NULL                }, WINED3D_GL_EXT_NONE             },
05566     { STATE_PIXELSHADER,                                  { STATE_PIXELSHADER,                                  apply_pixelshader   }, WINED3D_GL_EXT_NONE             },
05567     { STATE_RENDER(WINED3D_RS_SRGBWRITEENABLE),           { STATE_PIXELSHADER,                                  NULL                }, WINED3D_GL_EXT_NONE             },
05568     { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),             { STATE_RENDER(WINED3D_RS_TEXTUREFACTOR),             state_texfactor     }, WINED3D_GL_EXT_NONE             },
05569     { STATE_RENDER(WINED3D_RS_FOGCOLOR),                  { STATE_RENDER(WINED3D_RS_FOGCOLOR),                  state_fogcolor      }, WINED3D_GL_EXT_NONE             },
05570     { STATE_RENDER(WINED3D_RS_FOGDENSITY),                { STATE_RENDER(WINED3D_RS_FOGDENSITY),                state_fogdensity    }, WINED3D_GL_EXT_NONE             },
05571     { STATE_RENDER(WINED3D_RS_FOGENABLE),                 { STATE_RENDER(WINED3D_RS_FOGENABLE),                 state_fog_fragpart  }, WINED3D_GL_EXT_NONE             },
05572     { STATE_RENDER(WINED3D_RS_FOGTABLEMODE),              { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
05573     { STATE_RENDER(WINED3D_RS_FOGVERTEXMODE),             { STATE_RENDER(WINED3D_RS_FOGENABLE),                 NULL                }, WINED3D_GL_EXT_NONE             },
05574     { STATE_RENDER(WINED3D_RS_FOGSTART),                  { STATE_RENDER(WINED3D_RS_FOGSTART),                  state_fogstartend   }, WINED3D_GL_EXT_NONE             },
05575     { STATE_RENDER(WINED3D_RS_FOGEND),                    { STATE_RENDER(WINED3D_RS_FOGSTART),                  NULL                }, WINED3D_GL_EXT_NONE             },
05576     { STATE_SAMPLER(0),                                   { STATE_SAMPLER(0),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
05577     { STATE_SAMPLER(1),                                   { STATE_SAMPLER(1),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
05578     { STATE_SAMPLER(2),                                   { STATE_SAMPLER(2),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
05579     { STATE_SAMPLER(3),                                   { STATE_SAMPLER(3),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
05580     { STATE_SAMPLER(4),                                   { STATE_SAMPLER(4),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
05581     { STATE_SAMPLER(5),                                   { STATE_SAMPLER(5),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
05582     { STATE_SAMPLER(6),                                   { STATE_SAMPLER(6),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
05583     { STATE_SAMPLER(7),                                   { STATE_SAMPLER(7),                                   sampler_texdim      }, WINED3D_GL_EXT_NONE             },
05584     {0 /* Terminate */,                                   { 0,                                                  0                   }, WINED3D_GL_EXT_NONE             },
05585 };
05586 
05587 /* Context activation and GL locking are done by the caller. */
05588 static void ffp_enable(BOOL enable) {}
05589 
05590 static void ffp_fragment_get_caps(const struct wined3d_gl_info *gl_info, struct fragment_caps *caps)
05591 {
05592     caps->PrimitiveMiscCaps = 0;
05593     caps->TextureOpCaps = WINED3DTEXOPCAPS_ADD
05594             | WINED3DTEXOPCAPS_ADDSIGNED
05595             | WINED3DTEXOPCAPS_ADDSIGNED2X
05596             | WINED3DTEXOPCAPS_MODULATE
05597             | WINED3DTEXOPCAPS_MODULATE2X
05598             | WINED3DTEXOPCAPS_MODULATE4X
05599             | WINED3DTEXOPCAPS_SELECTARG1
05600             | WINED3DTEXOPCAPS_SELECTARG2
05601             | WINED3DTEXOPCAPS_DISABLE;
05602 
05603     if (gl_info->supported[ARB_TEXTURE_ENV_COMBINE]
05604             || gl_info->supported[EXT_TEXTURE_ENV_COMBINE]
05605             || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
05606     {
05607         caps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA
05608                 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHA
05609                 | WINED3DTEXOPCAPS_BLENDFACTORALPHA
05610                 | WINED3DTEXOPCAPS_BLENDCURRENTALPHA
05611                 | WINED3DTEXOPCAPS_LERP
05612                 | WINED3DTEXOPCAPS_SUBTRACT;
05613     }
05614     if (gl_info->supported[ATI_TEXTURE_ENV_COMBINE3]
05615             || gl_info->supported[NV_TEXTURE_ENV_COMBINE4])
05616     {
05617         caps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH
05618                 | WINED3DTEXOPCAPS_MULTIPLYADD
05619                 | WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR
05620                 | WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA
05621                 | WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
05622     }
05623     if (gl_info->supported[ARB_TEXTURE_ENV_DOT3])
05624         caps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
05625 
05626     caps->MaxTextureBlendStages = gl_info->limits.textures;
05627     caps->MaxSimultaneousTextures = gl_info->limits.textures;
05628 }
05629 
05630 static HRESULT ffp_fragment_alloc(struct wined3d_device *device) { return WINED3D_OK; }
05631 static void ffp_fragment_free(struct wined3d_device *device) {}
05632 static BOOL ffp_color_fixup_supported(struct color_fixup_desc fixup)
05633 {
05634     if (TRACE_ON(d3d))
05635     {
05636         TRACE("Checking support for fixup:\n");
05637         dump_color_fixup_desc(fixup);
05638     }
05639 
05640     /* We only support identity conversions. */
05641     if (is_identity_fixup(fixup))
05642     {
05643         TRACE("[OK]\n");
05644         return TRUE;
05645     }
05646 
05647     TRACE("[FAILED]\n");
05648     return FALSE;
05649 }
05650 
05651 const struct fragment_pipeline ffp_fragment_pipeline = {
05652     ffp_enable,
05653     ffp_fragment_get_caps,
05654     ffp_fragment_alloc,
05655     ffp_fragment_free,
05656     ffp_color_fixup_supported,
05657     ffp_fragmentstate_template,
05658     FALSE /* we cannot disable projected textures. The vertex pipe has to do it */
05659 };
05660 
05661 static unsigned int num_handlers(const APPLYSTATEFUNC *funcs)
05662 {
05663     unsigned int i;
05664     for(i = 0; funcs[i]; i++);
05665     return i;
05666 }
05667 
05668 static void multistate_apply_2(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
05669 {
05670     context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
05671     context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
05672 }
05673 
05674 static void multistate_apply_3(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
05675 {
05676     context->swapchain->device->multistate_funcs[state_id][0](context, state, state_id);
05677     context->swapchain->device->multistate_funcs[state_id][1](context, state, state_id);
05678     context->swapchain->device->multistate_funcs[state_id][2](context, state, state_id);
05679 }
05680 
05681 static void prune_invalid_states(struct StateEntry *state_table, const struct wined3d_gl_info *gl_info)
05682 {
05683     unsigned int start, last, i;
05684 
05685     start = STATE_TEXTURESTAGE(gl_info->limits.texture_stages, 0);
05686     last = STATE_TEXTURESTAGE(MAX_TEXTURES - 1, WINED3D_HIGHEST_TEXTURE_STATE);
05687     for (i = start; i <= last; ++i)
05688     {
05689         state_table[i].representative = 0;
05690         state_table[i].apply = state_undefined;
05691     }
05692 
05693     start = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + gl_info->limits.texture_stages);
05694     last = STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + MAX_TEXTURES - 1);
05695     for (i = start; i <= last; ++i)
05696     {
05697         state_table[i].representative = 0;
05698         state_table[i].apply = state_undefined;
05699     }
05700 
05701     start = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(gl_info->limits.blends));
05702     last = STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(255));
05703     for (i = start; i <= last; ++i)
05704     {
05705         state_table[i].representative = 0;
05706         state_table[i].apply = state_undefined;
05707     }
05708 }
05709 
05710 static void validate_state_table(struct StateEntry *state_table)
05711 {
05712     static const struct
05713     {
05714         DWORD first;
05715         DWORD last;
05716     }
05717     rs_holes[] =
05718     {
05719         {  1,   1},
05720         {  3,   3},
05721         { 17,  18},
05722         { 21,  21},
05723         { 42,  45},
05724         { 47,  47},
05725         { 61, 127},
05726         {149, 150},
05727         {169, 169},
05728         {177, 177},
05729         {196, 197},
05730         {  0,   0},
05731     };
05732     static const DWORD simple_states[] =
05733     {
05734         STATE_MATERIAL,
05735         STATE_VDECL,
05736         STATE_STREAMSRC,
05737         STATE_INDEXBUFFER,
05738         STATE_VERTEXSHADERCONSTANT,
05739         STATE_PIXELSHADERCONSTANT,
05740         STATE_VSHADER,
05741         STATE_PIXELSHADER,
05742         STATE_VIEWPORT,
05743         STATE_SCISSORRECT,
05744         STATE_FRONTFACE,
05745         STATE_POINTSPRITECOORDORIGIN,
05746         STATE_BASEVERTEXINDEX,
05747         STATE_FRAMEBUFFER
05748     };
05749     unsigned int i, current;
05750 
05751     for (i = STATE_RENDER(1), current = 0; i <= STATE_RENDER(WINEHIGHEST_RENDER_STATE); ++i)
05752     {
05753         if (!rs_holes[current].first || i < STATE_RENDER(rs_holes[current].first))
05754         {
05755             if (!state_table[i].representative)
05756                 ERR("State %s (%#x) should have a representative.\n", debug_d3dstate(i), i);
05757         }
05758         else if (state_table[i].representative)
05759             ERR("State %s (%#x) shouldn't have a representative.\n", debug_d3dstate(i), i);
05760 
05761         if (i == STATE_RENDER(rs_holes[current].last)) ++current;
05762     }
05763 
05764     for (i = 0; i < sizeof(simple_states) / sizeof(*simple_states); ++i)
05765     {
05766         if (!state_table[simple_states[i]].representative)
05767             ERR("State %s (%#x) should have a representative.\n",
05768                     debug_d3dstate(simple_states[i]), simple_states[i]);
05769     }
05770 
05771     for (i = 0; i < STATE_HIGHEST + 1; ++i)
05772     {
05773         DWORD rep = state_table[i].representative;
05774         if (rep)
05775         {
05776             if (state_table[rep].representative != rep)
05777             {
05778                 ERR("State %s (%#x) has invalid representative %s (%#x).\n",
05779                         debug_d3dstate(i), i, debug_d3dstate(rep), rep);
05780                 state_table[i].representative = 0;
05781             }
05782 
05783             if (rep != i)
05784             {
05785                 if (state_table[i].apply)
05786                     ERR("State %s (%#x) has both a handler and representative.\n", debug_d3dstate(i), i);
05787             }
05788             else if (!state_table[i].apply)
05789             {
05790                 ERR("Self representing state %s (%#x) has no handler.\n", debug_d3dstate(i), i);
05791             }
05792         }
05793     }
05794 }
05795 
05796 HRESULT compile_state_table(struct StateEntry *StateTable, APPLYSTATEFUNC **dev_multistate_funcs,
05797         const struct wined3d_gl_info *gl_info, const struct StateEntryTemplate *vertex,
05798         const struct fragment_pipeline *fragment, const struct StateEntryTemplate *misc)
05799 {
05800     unsigned int i, type, handlers;
05801     APPLYSTATEFUNC multistate_funcs[STATE_HIGHEST + 1][3];
05802     const struct StateEntryTemplate *cur;
05803     BOOL set[STATE_HIGHEST + 1];
05804 
05805     memset(multistate_funcs, 0, sizeof(multistate_funcs));
05806 
05807     for(i = 0; i < STATE_HIGHEST + 1; i++) {
05808         StateTable[i].representative = 0;
05809         StateTable[i].apply = state_undefined;
05810     }
05811 
05812     for(type = 0; type < 3; type++) {
05813         /* This switch decides the order in which the states are applied */
05814         switch(type) {
05815             case 0: cur = misc; break;
05816             case 1: cur = fragment->states; break;
05817             case 2: cur = vertex; break;
05818             default: cur = NULL; /* Stupid compiler */
05819         }
05820         if(!cur) continue;
05821 
05822         /* GL extension filtering should not prevent multiple handlers being applied from different
05823          * pipeline parts
05824          */
05825         memset(set, 0, sizeof(set));
05826 
05827         for(i = 0; cur[i].state; i++) {
05828             APPLYSTATEFUNC *funcs_array;
05829 
05830             /* Only use the first matching state with the available extension from one template.
05831              * e.g.
05832              * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func1}, XYZ_FANCY},
05833              * {D3DRS_FOOBAR, {D3DRS_FOOBAR, func2}, 0        }
05834              *
05835              * if GL_XYZ_fancy is supported, ignore the 2nd line
05836              */
05837             if(set[cur[i].state]) continue;
05838             /* Skip state lines depending on unsupported extensions */
05839             if (!gl_info->supported[cur[i].extension]) continue;
05840             set[cur[i].state] = TRUE;
05841             /* In some cases having an extension means that nothing has to be
05842              * done for a state, e.g. if GL_ARB_texture_non_power_of_two is
05843              * supported, the texture coordinate fixup can be ignored. If the
05844              * apply function is used, mark the state set(done above) to prevent
05845              * applying later lines, but do not record anything in the state
05846              * table
05847              */
05848             if (!cur[i].content.representative) continue;
05849 
05850             handlers = num_handlers(multistate_funcs[cur[i].state]);
05851             multistate_funcs[cur[i].state][handlers] = cur[i].content.apply;
05852             switch(handlers) {
05853                 case 0:
05854                     StateTable[cur[i].state].apply = cur[i].content.apply;
05855                     break;
05856                 case 1:
05857                     StateTable[cur[i].state].apply = multistate_apply_2;
05858                     dev_multistate_funcs[cur[i].state] = HeapAlloc(GetProcessHeap(),
05859                                                                    0,
05860                                                                    sizeof(**dev_multistate_funcs) * 2);
05861                     if (!dev_multistate_funcs[cur[i].state]) {
05862                         goto out_of_mem;
05863                     }
05864 
05865                     dev_multistate_funcs[cur[i].state][0] = multistate_funcs[cur[i].state][0];
05866                     dev_multistate_funcs[cur[i].state][1] = multistate_funcs[cur[i].state][1];
05867                     break;
05868                 case 2:
05869                     StateTable[cur[i].state].apply = multistate_apply_3;
05870                     funcs_array = HeapReAlloc(GetProcessHeap(),
05871                                               0,
05872                                               dev_multistate_funcs[cur[i].state],
05873                                               sizeof(**dev_multistate_funcs) * 3);
05874                     if (!funcs_array) {
05875                         goto out_of_mem;
05876                     }
05877 
05878                     dev_multistate_funcs[cur[i].state] = funcs_array;
05879                     dev_multistate_funcs[cur[i].state][2] = multistate_funcs[cur[i].state][2];
05880                     break;
05881                 default:
05882                     ERR("Unexpected amount of state handlers for state %u: %u\n",
05883                         cur[i].state, handlers + 1);
05884             }
05885 
05886             if(StateTable[cur[i].state].representative &&
05887             StateTable[cur[i].state].representative != cur[i].content.representative) {
05888                 FIXME("State %u has different representatives in different pipeline parts\n",
05889                     cur[i].state);
05890             }
05891             StateTable[cur[i].state].representative = cur[i].content.representative;
05892         }
05893     }
05894 
05895     prune_invalid_states(StateTable, gl_info);
05896     validate_state_table(StateTable);
05897 
05898     return WINED3D_OK;
05899 
05900 out_of_mem:
05901     for (i = 0; i <= STATE_HIGHEST; ++i) {
05902         HeapFree(GetProcessHeap(), 0, dev_multistate_funcs[i]);
05903     }
05904 
05905     memset(dev_multistate_funcs, 0, (STATE_HIGHEST + 1)*sizeof(*dev_multistate_funcs));
05906 
05907     return E_OUTOFMEMORY;
05908 }

Generated on Fri May 25 2012 04:18:34 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.