wined3d: Make the shader mode selections per device.

oldstable
Ivan Gyurdiev 2006-10-07 23:25:01 -04:00 committed by Alexandre Julliard
parent 3ce4350e67
commit e020eceddf
7 changed files with 50 additions and 43 deletions

View File

@ -317,7 +317,7 @@ void set_glsl_shader_program(IWineD3DDevice *iface) {
This->stateBlock->glsl_program = newLink; This->stateBlock->glsl_program = newLink;
/* Attach GLSL vshader */ /* Attach GLSL vshader */
if (NULL != vshader && wined3d_settings.vs_selected_mode == SHADER_GLSL) { if (NULL != vshader && This->vs_selected_mode == SHADER_GLSL) {
int i; int i;
int max_attribs = 16; /* TODO: Will this always be the case? It is at the moment... */ int max_attribs = 16; /* TODO: Will this always be the case? It is at the moment... */
char tmp_name[10]; char tmp_name[10];
@ -343,7 +343,7 @@ void set_glsl_shader_program(IWineD3DDevice *iface) {
} }
/* Attach GLSL pshader */ /* Attach GLSL pshader */
if (NULL != pshader && wined3d_settings.ps_selected_mode == SHADER_GLSL) { if (NULL != pshader && This->ps_selected_mode == SHADER_GLSL) {
TRACE("Attaching pixel shader to GLSL program\n"); TRACE("Attaching pixel shader to GLSL program\n");
attach_glsl_shader(iface, (IWineD3DBaseShader*)pshader); attach_glsl_shader(iface, (IWineD3DBaseShader*)pshader);
newLink->pixelShader = pshader; newLink->pixelShader = pshader;
@ -574,8 +574,8 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) {
** ***************************/ ** ***************************/
/* Delete any GLSL shader programs that may exist */ /* Delete any GLSL shader programs that may exist */
if (wined3d_settings.vs_selected_mode == SHADER_GLSL || if (This->vs_selected_mode == SHADER_GLSL ||
wined3d_settings.ps_selected_mode == SHADER_GLSL) This->ps_selected_mode == SHADER_GLSL)
delete_glsl_shader_list(iface); delete_glsl_shader_list(iface);
/* Release the update stateblock */ /* Release the update stateblock */

View File

@ -238,9 +238,12 @@ static void select_shader_mode(
} }
/** Select the number of report maximum shader constants based on the selected shader modes */ /** Select the number of report maximum shader constants based on the selected shader modes */
void select_shader_max_constants(WineD3D_GL_Info *gl_info) { void select_shader_max_constants(
int ps_selected_mode,
int vs_selected_mode,
WineD3D_GL_Info *gl_info) {
switch (wined3d_settings.vs_selected_mode) { switch (vs_selected_mode) {
case SHADER_GLSL: case SHADER_GLSL:
/* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */ /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - MAX_CONST_B - MAX_CONST_I - 1; gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - MAX_CONST_B - MAX_CONST_I - 1;
@ -259,7 +262,7 @@ void select_shader_max_constants(WineD3D_GL_Info *gl_info) {
break; break;
} }
switch (wined3d_settings.ps_selected_mode) { switch (ps_selected_mode) {
case SHADER_GLSL: case SHADER_GLSL:
/* Subtract the other potential uniforms from the max available (bools & ints) */ /* Subtract the other potential uniforms from the max available (bools & ints) */
gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - MAX_CONST_B - MAX_CONST_I; gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - MAX_CONST_B - MAX_CONST_I;
@ -1808,6 +1811,8 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface,
static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) { static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
IWineD3DImpl *This = (IWineD3DImpl *)iface; IWineD3DImpl *This = (IWineD3DImpl *)iface;
int vs_selected_mode;
int ps_selected_mode;
TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps); TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
@ -1815,7 +1820,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
return WINED3DERR_INVALIDCALL; return WINED3DERR_INVALIDCALL;
} }
/* FIXME: both the gl_info and the shader_mode should be made per adapter */ /* FIXME: GL info should be per adapter */
/* If we don't know the device settings, go query them now */ /* If we don't know the device settings, go query them now */
if (!This->isGLInfoValid) { if (!This->isGLInfoValid) {
@ -1825,9 +1830,11 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
/* We are running off a real context, save the values */ /* We are running off a real context, save the values */
if (rc) This->isGLInfoValid = TRUE; if (rc) This->isGLInfoValid = TRUE;
} }
select_shader_mode(&This->gl_info, DeviceType, select_shader_mode(&This->gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
&wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
select_shader_max_constants(&This->gl_info); /* This function should *not* be modifying GL caps
* TODO: move the functionality where it belongs */
select_shader_max_constants(ps_selected_mode, vs_selected_mode, &This->gl_info);
/* ------------------------------------------------ /* ------------------------------------------------
The following fields apply to both d3d8 and d3d9 The following fields apply to both d3d8 and d3d9
@ -2192,8 +2199,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
*pCaps->MaxStreams = MAX_STREAMS; *pCaps->MaxStreams = MAX_STREAMS;
*pCaps->MaxStreamStride = 1024; *pCaps->MaxStreamStride = 1024;
/* FIXME: the shader mode should be per adapter */ if (vs_selected_mode == SHADER_GLSL) {
if (wined3d_settings.vs_selected_mode == SHADER_GLSL) {
/* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati
models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using
vs_nv_version which is based on NV_vertex_program. For Ati cards there's no easy way, so for vs_nv_version which is based on NV_vertex_program. For Ati cards there's no easy way, so for
@ -2203,10 +2209,10 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
else else
*pCaps->VertexShaderVersion = D3DVS_VERSION(3,0); *pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n"); TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n");
} else if (wined3d_settings.vs_selected_mode == SHADER_ARB) { } else if (vs_selected_mode == SHADER_ARB) {
*pCaps->VertexShaderVersion = D3DVS_VERSION(1,1); *pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n"); TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
} else if (wined3d_settings.vs_selected_mode == SHADER_SW) { } else if (vs_selected_mode == SHADER_SW) {
*pCaps->VertexShaderVersion = D3DVS_VERSION(3,0); *pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
TRACE_(d3d_caps)("Software vertex shader version 3.0 enabled\n"); TRACE_(d3d_caps)("Software vertex shader version 3.0 enabled\n");
} else { } else {
@ -2216,8 +2222,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
*pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF); *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
/* FIXME: the shader mode should be per adapter */ if (ps_selected_mode == SHADER_GLSL) {
if (wined3d_settings.ps_selected_mode == SHADER_GLSL) {
/* See the comment about VS2.0/VS3.0 detection as we do the same here but then based on NV_fragment_program /* See the comment about VS2.0/VS3.0 detection as we do the same here but then based on NV_fragment_program
in case of GeforceFX cards. */ in case of GeforceFX cards. */
if(This->gl_info.ps_nv_version == PS_VERSION_20) if(This->gl_info.ps_nv_version == PS_VERSION_20)
@ -2227,12 +2232,12 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
/* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */ /* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */
*pCaps->PixelShader1xMaxValue = 1.0; *pCaps->PixelShader1xMaxValue = 1.0;
TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n"); TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n");
} else if (wined3d_settings.ps_selected_mode == SHADER_ARB) { } else if (ps_selected_mode == SHADER_ARB) {
*pCaps->PixelShaderVersion = D3DPS_VERSION(1,4); *pCaps->PixelShaderVersion = D3DPS_VERSION(1,4);
*pCaps->PixelShader1xMaxValue = 1.0; *pCaps->PixelShader1xMaxValue = 1.0;
TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n"); TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
/* FIXME: Uncomment this when there is support for software Pixel Shader 3.0 and PS_SW is defined /* FIXME: Uncomment this when there is support for software Pixel Shader 3.0 and PS_SW is defined
} else if (wined3d_settings.ps_selected_mode = SHADER_SW) { } else if (ps_selected_mode = SHADER_SW) {
*pCaps->PixelShaderVersion = D3DPS_VERSION(3,0); *pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
*pCaps->PixelShader1xMaxValue = 1.0; *pCaps->PixelShader1xMaxValue = 1.0;
TRACE_(d3d_caps)("Software pixel shader version 3.0 enabled\n"); */ TRACE_(d3d_caps)("Software pixel shader version 3.0 enabled\n"); */
@ -2413,12 +2418,14 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
/* Setup some defaults for creating the implicit swapchain */ /* Setup some defaults for creating the implicit swapchain */
ENTER_GL(); ENTER_GL();
/* FIXME: both of those should be made per adapter */ /* FIXME: GL info should be per adapter */
IWineD3DImpl_FillGLCaps(iface, IWineD3DImpl_GetAdapterDisplay(iface, Adapter)); IWineD3DImpl_FillGLCaps(iface, IWineD3DImpl_GetAdapterDisplay(iface, Adapter));
LEAVE_GL(); LEAVE_GL();
select_shader_mode(&This->gl_info, DeviceType, select_shader_mode(&This->gl_info, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
&wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
select_shader_max_constants(&This->gl_info); /* This function should *not* be modifying GL caps
* TODO: move the functionality where it belongs */
select_shader_max_constants(object->ps_selected_mode, object->vs_selected_mode, &This->gl_info);
temp_result = allocate_shader_constants(object->updateStateBlock); temp_result = allocate_shader_constants(object->updateStateBlock);
if (WINED3D_OK != temp_result) if (WINED3D_OK != temp_result)

View File

@ -1797,15 +1797,14 @@ inline static void drawPrimitiveDrawStrided(
} }
/* If GLSL is used for either pixel or vertex shaders, make a GLSL program /* If GLSL is used for either pixel or vertex shaders, make a GLSL program
* Otherwise set NULL, to restore fixed function */ * Otherwise set NULL, to restore fixed function */
if ((wined3d_settings.vs_selected_mode == SHADER_GLSL && useVertexShaderFunction) || if ((This->vs_selected_mode == SHADER_GLSL && useVertexShaderFunction) ||
(wined3d_settings.ps_selected_mode == SHADER_GLSL && usePixelShaderFunction)) (This->ps_selected_mode == SHADER_GLSL && usePixelShaderFunction))
set_glsl_shader_program(iface); set_glsl_shader_program(iface);
else else
This->stateBlock->glsl_program = NULL; This->stateBlock->glsl_program = NULL;
/* If GLSL is used now, or might have been used before, (re)set the program */ /* If GLSL is used now, or might have been used before, (re)set the program */
if (wined3d_settings.vs_selected_mode == SHADER_GLSL || if (This->vs_selected_mode == SHADER_GLSL || This->ps_selected_mode == SHADER_GLSL) {
wined3d_settings.ps_selected_mode == SHADER_GLSL) {
GLhandleARB progId = This->stateBlock->glsl_program ? This->stateBlock->glsl_program->programId : 0; GLhandleARB progId = This->stateBlock->glsl_program ? This->stateBlock->glsl_program->programId : 0;
if (progId) if (progId)
@ -1818,7 +1817,7 @@ inline static void drawPrimitiveDrawStrided(
TRACE("Using vertex shader\n"); TRACE("Using vertex shader\n");
if (wined3d_settings.vs_selected_mode == SHADER_ARB) { if (This->vs_selected_mode == SHADER_ARB) {
/* Bind the vertex program */ /* Bind the vertex program */
GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB,
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.prgId)); ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.prgId));
@ -1836,7 +1835,7 @@ inline static void drawPrimitiveDrawStrided(
TRACE("Using pixel shader\n"); TRACE("Using pixel shader\n");
if (wined3d_settings.ps_selected_mode == SHADER_ARB) { if (This->ps_selected_mode == SHADER_ARB) {
/* Bind the fragment program */ /* Bind the fragment program */
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB,
((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId)); ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId));
@ -1848,12 +1847,12 @@ inline static void drawPrimitiveDrawStrided(
TRACE_(d3d_shader)("(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n", TRACE_(d3d_shader)("(%p) : Bound fragment program %u and enabled GL_FRAGMENT_PROGRAM_ARB\n",
This, ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId); This, ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId);
} }
} }
/* Load any global constants/uniforms that may have been set by the application */ /* Load any global constants/uniforms that may have been set by the application */
if (wined3d_settings.vs_selected_mode == SHADER_GLSL || wined3d_settings.ps_selected_mode == SHADER_GLSL) if (This->vs_selected_mode == SHADER_GLSL || This->ps_selected_mode == SHADER_GLSL)
shader_glsl_load_constants(iface, usePixelShaderFunction, useVertexShaderFunction); shader_glsl_load_constants(iface, usePixelShaderFunction, useVertexShaderFunction);
else if (wined3d_settings.vs_selected_mode== SHADER_ARB || wined3d_settings.ps_selected_mode == SHADER_ARB) else if (This->vs_selected_mode == SHADER_ARB || This->ps_selected_mode == SHADER_ARB)
shader_arb_load_constants(iface, usePixelShaderFunction, useVertexShaderFunction); shader_arb_load_constants(iface, usePixelShaderFunction, useVertexShaderFunction);
/* Draw vertex-by-vertex */ /* Draw vertex-by-vertex */
@ -1866,14 +1865,14 @@ inline static void drawPrimitiveDrawStrided(
if (useVertexShaderFunction) { if (useVertexShaderFunction) {
unloadNumberedArrays(iface); unloadNumberedArrays(iface);
if (wined3d_settings.vs_selected_mode == SHADER_ARB) if (This->vs_selected_mode == SHADER_ARB)
glDisable(GL_VERTEX_PROGRAM_ARB); glDisable(GL_VERTEX_PROGRAM_ARB);
} else { } else {
unloadVertexData(iface); unloadVertexData(iface);
} }
/* Cleanup fragment program */ /* Cleanup fragment program */
if (usePixelShaderFunction && wined3d_settings.ps_selected_mode == SHADER_ARB) if (usePixelShaderFunction && This->ps_selected_mode == SHADER_ARB)
glDisable(GL_FRAGMENT_PROGRAM_ARB); glDisable(GL_FRAGMENT_PROGRAM_ARB);
} }
@ -2100,11 +2099,11 @@ void drawPrimitive(IWineD3DDevice *iface,
/* Shaders can be implemented using ARB_PROGRAM, GLSL, or software - /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
* here simply check whether a shader was set, or the user disabled shaders */ * here simply check whether a shader was set, or the user disabled shaders */
if (wined3d_settings.vs_selected_mode != SHADER_NONE && This->stateBlock->vertexShader && if (This->vs_selected_mode != SHADER_NONE && This->stateBlock->vertexShader &&
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.function != NULL) ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.function != NULL)
useVertexShaderFunction = TRUE; useVertexShaderFunction = TRUE;
if (wined3d_settings.ps_selected_mode != SHADER_NONE && This->stateBlock->pixelShader && if (This->ps_selected_mode != SHADER_NONE && This->stateBlock->pixelShader &&
((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function) ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function)
usePixelShaderFunction = TRUE; usePixelShaderFunction = TRUE;

View File

@ -870,7 +870,7 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
/* Store the shader object */ /* Store the shader object */
This->baseShader.prgId = shader_obj; This->baseShader.prgId = shader_obj;
} else if (wined3d_settings.ps_selected_mode == SHADER_ARB) { } else if (This->baseShader.shader_mode == SHADER_ARB) {
/* Create the hw ARB shader */ /* Create the hw ARB shader */
shader_addline(&buffer, "!!ARBfp1.0\n"); shader_addline(&buffer, "!!ARBfp1.0\n");
@ -921,6 +921,7 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) { static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface; IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
TRACE("(%p) : pFunction %p\n", iface, pFunction); TRACE("(%p) : pFunction %p\n", iface, pFunction);
@ -933,7 +934,7 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
list_init(&This->baseShader.constantsB); list_init(&This->baseShader.constantsB);
list_init(&This->baseShader.constantsI); list_init(&This->baseShader.constantsI);
This->baseShader.shader_mode = wined3d_settings.ps_selected_mode; This->baseShader.shader_mode = deviceImpl->ps_selected_mode;
TRACE("(%p) : Copying the function\n", This); TRACE("(%p) : Copying the function\n", This);
if (NULL != pFunction) { if (NULL != pFunction) {

View File

@ -1207,7 +1207,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
This->semantics_in, This->semantics_out, pFunction, deviceImpl->stateBlock); This->semantics_in, This->semantics_out, pFunction, deviceImpl->stateBlock);
if (hr != WINED3D_OK) return hr; if (hr != WINED3D_OK) return hr;
This->baseShader.shader_mode = wined3d_settings.vs_selected_mode; This->baseShader.shader_mode = deviceImpl->vs_selected_mode;
/* copy the function ... because it will certainly be released by application */ /* copy the function ... because it will certainly be released by application */
if (NULL != pFunction) { if (NULL != pFunction) {

View File

@ -40,8 +40,6 @@ wined3d_settings_t wined3d_settings =
PS_HW, /* Hardware by default */ PS_HW, /* Hardware by default */
VBO_HW, /* Hardware by default */ VBO_HW, /* Hardware by default */
FALSE, /* Use of GLSL disabled by default */ FALSE, /* Use of GLSL disabled by default */
SHADER_ARB, /* Use ARB vertex programs, when available */
SHADER_ARB, /* Use ARB fragment programs, when available */
NP2_NATIVE, /* Use native NPOT textures, when available */ NP2_NATIVE, /* Use native NPOT textures, when available */
RTL_AUTO, /* Automatically determine best locking method */ RTL_AUTO, /* Automatically determine best locking method */
64*1024*1024 /* 64MB texture memory by default */ 64*1024*1024 /* 64MB texture memory by default */

View File

@ -157,8 +157,6 @@ typedef struct wined3d_settings_s {
we should use it. However, until it's fully implemented, we'll leave it as a registry we should use it. However, until it's fully implemented, we'll leave it as a registry
setting for developers. */ setting for developers. */
BOOL glslRequested; BOOL glslRequested;
int vs_selected_mode;
int ps_selected_mode;
/* nonpower 2 function */ /* nonpower 2 function */
int nonpower2_mode; int nonpower2_mode;
int rendertargetlock_mode; int rendertargetlock_mode;
@ -499,6 +497,10 @@ typedef struct IWineD3DDeviceImpl
/* X and GL Information */ /* X and GL Information */
GLint maxConcurrentLights; GLint maxConcurrentLights;
/* Selected capabilities */
int vs_selected_mode;
int ps_selected_mode;
/* Optimization */ /* Optimization */
BOOL modelview_valid; BOOL modelview_valid;
BOOL proj_valid; BOOL proj_valid;