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;
/* 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 max_attribs = 16; /* TODO: Will this always be the case? It is at the moment... */
char tmp_name[10];
@ -343,7 +343,7 @@ void set_glsl_shader_program(IWineD3DDevice *iface) {
}
/* 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");
attach_glsl_shader(iface, (IWineD3DBaseShader*)pshader);
newLink->pixelShader = pshader;
@ -574,8 +574,8 @@ static ULONG WINAPI IWineD3DDeviceImpl_Release(IWineD3DDevice *iface) {
** ***************************/
/* Delete any GLSL shader programs that may exist */
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)
delete_glsl_shader_list(iface);
/* 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 */
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:
/* 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;
@ -259,7 +262,7 @@ void select_shader_max_constants(WineD3D_GL_Info *gl_info) {
break;
}
switch (wined3d_settings.ps_selected_mode) {
switch (ps_selected_mode) {
case SHADER_GLSL:
/* 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;
@ -1808,6 +1811,8 @@ static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion(IWineD3D *iface,
static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
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);
@ -1815,7 +1820,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
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 (!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 */
if (rc) This->isGLInfoValid = TRUE;
}
select_shader_mode(&This->gl_info, DeviceType,
&wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
select_shader_max_constants(&This->gl_info);
select_shader_mode(&This->gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
/* 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
@ -2192,8 +2199,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
*pCaps->MaxStreams = MAX_STREAMS;
*pCaps->MaxStreamStride = 1024;
/* FIXME: the shader mode should be per adapter */
if (wined3d_settings.vs_selected_mode == SHADER_GLSL) {
if (vs_selected_mode == SHADER_GLSL) {
/* 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
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
*pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
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);
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);
TRACE_(d3d_caps)("Software vertex shader version 3.0 enabled\n");
} else {
@ -2216,8 +2222,7 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
*pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF);
/* FIXME: the shader mode should be per adapter */
if (wined3d_settings.ps_selected_mode == SHADER_GLSL) {
if (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
in case of GeforceFX cards. */
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 */
*pCaps->PixelShader1xMaxValue = 1.0;
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->PixelShader1xMaxValue = 1.0;
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
} else if (wined3d_settings.ps_selected_mode = SHADER_SW) {
} else if (ps_selected_mode = SHADER_SW) {
*pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
*pCaps->PixelShader1xMaxValue = 1.0;
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 */
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));
LEAVE_GL();
select_shader_mode(&This->gl_info, DeviceType,
&wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
select_shader_max_constants(&This->gl_info);
select_shader_mode(&This->gl_info, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
/* 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);
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
* Otherwise set NULL, to restore fixed function */
if ((wined3d_settings.vs_selected_mode == SHADER_GLSL && useVertexShaderFunction) ||
(wined3d_settings.ps_selected_mode == SHADER_GLSL && usePixelShaderFunction))
if ((This->vs_selected_mode == SHADER_GLSL && useVertexShaderFunction) ||
(This->ps_selected_mode == SHADER_GLSL && usePixelShaderFunction))
set_glsl_shader_program(iface);
else
This->stateBlock->glsl_program = NULL;
/* If GLSL is used now, or might have been used before, (re)set the program */
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) {
GLhandleARB progId = This->stateBlock->glsl_program ? This->stateBlock->glsl_program->programId : 0;
if (progId)
@ -1818,7 +1817,7 @@ inline static void drawPrimitiveDrawStrided(
TRACE("Using vertex shader\n");
if (wined3d_settings.vs_selected_mode == SHADER_ARB) {
if (This->vs_selected_mode == SHADER_ARB) {
/* Bind the vertex program */
GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB,
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.prgId));
@ -1836,7 +1835,7 @@ inline static void drawPrimitiveDrawStrided(
TRACE("Using pixel shader\n");
if (wined3d_settings.ps_selected_mode == SHADER_ARB) {
if (This->ps_selected_mode == SHADER_ARB) {
/* Bind the fragment program */
GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB,
((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",
This, ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId);
}
}
}
/* 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);
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);
/* Draw vertex-by-vertex */
@ -1866,14 +1865,14 @@ inline static void drawPrimitiveDrawStrided(
if (useVertexShaderFunction) {
unloadNumberedArrays(iface);
if (wined3d_settings.vs_selected_mode == SHADER_ARB)
if (This->vs_selected_mode == SHADER_ARB)
glDisable(GL_VERTEX_PROGRAM_ARB);
} else {
unloadVertexData(iface);
}
/* 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);
}
@ -2100,11 +2099,11 @@ void drawPrimitive(IWineD3DDevice *iface,
/* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
* 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)
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)
usePixelShaderFunction = TRUE;

View File

@ -870,7 +870,7 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
/* Store the shader object */
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 */
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) {
IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
IWineD3DDeviceImpl *deviceImpl = (IWineD3DDeviceImpl *) This->baseShader.device;
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.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);
if (NULL != pFunction) {

View File

@ -1207,7 +1207,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
This->semantics_in, This->semantics_out, pFunction, deviceImpl->stateBlock);
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 */
if (NULL != pFunction) {

View File

@ -40,8 +40,6 @@ wined3d_settings_t wined3d_settings =
PS_HW, /* Hardware by default */
VBO_HW, /* Hardware 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 */
RTL_AUTO, /* Automatically determine best locking method */
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
setting for developers. */
BOOL glslRequested;
int vs_selected_mode;
int ps_selected_mode;
/* nonpower 2 function */
int nonpower2_mode;
int rendertargetlock_mode;
@ -499,6 +497,10 @@ typedef struct IWineD3DDeviceImpl
/* X and GL Information */
GLint maxConcurrentLights;
/* Selected capabilities */
int vs_selected_mode;
int ps_selected_mode;
/* Optimization */
BOOL modelview_valid;
BOOL proj_valid;