mirror of
https://github.com/reactos/wine.git
synced 2024-11-26 05:00:30 +00:00
wined3d: Make the shader mode selections per device.
This commit is contained in:
parent
3ce4350e67
commit
e020eceddf
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user