wined3d: Rework shader mode selection.
- currently half the shader selection code (GLSL vs ARB) is in fillGLcaps. The parts that check for software shaders are in GetDeviceCaps. That placement, will work, but is definitely not optimal. FillGLcaps should detect support - it should not make decision as to what's used, because that's not what the purpose of the function is. GetDeviceCaps should report support as it has already been selected. Instead, select shader mode in its own function, called in the appropriate places. - unifying pixel and vertex shaders into a single selection is a mistake. A software vertex shader can be coupled with a hardware arb or glsl pixel shader, or no shader at all. Split them back into two and add a SHADER_NONE variant. - drawprim is doing support checks for ARB_PROGRAM, and making shader decisions based on that - that's wrong, support has already been checked, and decided upon, and shaders can be implemented via software, ARB_PROGRAm or GLSL, so that support check isn't valid. - Store the shader selected mode into the shader itself. Different types of shaders can be combined, so this is an improvement. In fact, storing the mode into the settings globally is a mistake as well - it should be done per device, since different cards have different capabilities.
This commit is contained in:
parent
010f5729dd
commit
771623692e
|
@ -747,9 +747,14 @@ void shader_generate_main(
|
||||||
/* Read opcode */
|
/* Read opcode */
|
||||||
opcode_token = *pToken++;
|
opcode_token = *pToken++;
|
||||||
curOpcode = shader_get_opcode(iface, opcode_token);
|
curOpcode = shader_get_opcode(iface, opcode_token);
|
||||||
hw_fct = (curOpcode == NULL)? NULL:
|
|
||||||
(wined3d_settings.shader_mode == SHADER_GLSL)?
|
/* Select handler */
|
||||||
curOpcode->hw_glsl_fct : curOpcode->hw_fct;
|
if (curOpcode == NULL)
|
||||||
|
hw_fct = NULL;
|
||||||
|
else if (This->baseShader.shader_mode == SHADER_GLSL)
|
||||||
|
hw_fct = curOpcode->hw_glsl_fct;
|
||||||
|
else if (This->baseShader.shader_mode == SHADER_ARB)
|
||||||
|
hw_fct = curOpcode->hw_fct;
|
||||||
|
|
||||||
/* Unknown opcode and its parameters */
|
/* Unknown opcode and its parameters */
|
||||||
if (NULL == curOpcode) {
|
if (NULL == curOpcode) {
|
||||||
|
@ -802,7 +807,7 @@ void shader_generate_main(
|
||||||
hw_fct(&hw_arg);
|
hw_fct(&hw_arg);
|
||||||
|
|
||||||
/* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
|
/* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
|
||||||
if (wined3d_settings.shader_mode == SHADER_GLSL)
|
if (This->baseShader.shader_mode == SHADER_GLSL)
|
||||||
shader_glsl_add_instruction_modifiers(&hw_arg);
|
shader_glsl_add_instruction_modifiers(&hw_arg);
|
||||||
|
|
||||||
/* Unhandled opcode */
|
/* Unhandled opcode */
|
||||||
|
|
|
@ -567,9 +567,9 @@ 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.shader_mode == SHADER_GLSL) {
|
if (wined3d_settings.vs_selected_mode == SHADER_GLSL ||
|
||||||
|
wined3d_settings.ps_selected_mode == SHADER_GLSL)
|
||||||
delete_glsl_shader_list(iface);
|
delete_glsl_shader_list(iface);
|
||||||
}
|
|
||||||
|
|
||||||
/* Release the update stateblock */
|
/* Release the update stateblock */
|
||||||
if(IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->updateStateBlock) > 0){
|
if(IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->updateStateBlock) > 0){
|
||||||
|
|
|
@ -199,6 +199,43 @@ static ULONG WINAPI IWineD3DImpl_Release(IWineD3D *iface) {
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set the shader type for this device, depending on the given capabilities,
|
||||||
|
* the device type, and the user preferences in wined3d_settings */
|
||||||
|
|
||||||
|
static void select_shader_mode(
|
||||||
|
WineD3D_GL_Info *gl_info,
|
||||||
|
WINED3DDEVTYPE DeviceType,
|
||||||
|
int* ps_selected,
|
||||||
|
int* vs_selected) {
|
||||||
|
|
||||||
|
/* Give priority to user disable/emulation request.
|
||||||
|
* Then respect REF device for software.
|
||||||
|
* Then check capabilities for hardware, and fallback to software */
|
||||||
|
|
||||||
|
if (wined3d_settings.vs_mode == VS_NONE)
|
||||||
|
*vs_selected = SHADER_NONE;
|
||||||
|
else if (DeviceType == WINED3DDEVTYPE_REF || wined3d_settings.vs_mode == VS_SW)
|
||||||
|
*vs_selected = SHADER_SW;
|
||||||
|
else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested)
|
||||||
|
*vs_selected = SHADER_GLSL;
|
||||||
|
else if (gl_info->supported[ARB_VERTEX_PROGRAM])
|
||||||
|
*vs_selected = SHADER_ARB;
|
||||||
|
else
|
||||||
|
*vs_selected = SHADER_SW;
|
||||||
|
|
||||||
|
/* Fallback to SHADER_NONE where software pixel shaders should be used */
|
||||||
|
if (wined3d_settings.ps_mode == PS_NONE)
|
||||||
|
*ps_selected = SHADER_NONE;
|
||||||
|
else if (DeviceType == WINED3DDEVTYPE_REF)
|
||||||
|
*ps_selected = SHADER_NONE;
|
||||||
|
else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested)
|
||||||
|
*ps_selected = SHADER_GLSL;
|
||||||
|
else if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
|
||||||
|
*ps_selected = SHADER_ARB;
|
||||||
|
else
|
||||||
|
*ps_selected = SHADER_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* IWineD3D parts follows
|
* IWineD3D parts follows
|
||||||
**********************************************************/
|
**********************************************************/
|
||||||
|
@ -752,17 +789,6 @@ BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info, Display* display) {
|
||||||
GLX_EXT_FUNCS_GEN;
|
GLX_EXT_FUNCS_GEN;
|
||||||
#undef USE_GL_FUNC
|
#undef USE_GL_FUNC
|
||||||
|
|
||||||
/* Determine shader mode to use based on GL caps */
|
|
||||||
if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested
|
|
||||||
&& (wined3d_settings.vs_mode == VS_HW || wined3d_settings.ps_mode == PS_HW))
|
|
||||||
wined3d_settings.shader_mode = SHADER_GLSL;
|
|
||||||
else if ((gl_info->supported[ARB_VERTEX_PROGRAM] && wined3d_settings.vs_mode == VS_HW) ||
|
|
||||||
(gl_info->supported[ARB_FRAGMENT_PROGRAM] && wined3d_settings.ps_mode == PS_HW))
|
|
||||||
wined3d_settings.shader_mode = SHADER_ARB;
|
|
||||||
else
|
|
||||||
wined3d_settings.shader_mode = SHADER_SW;
|
|
||||||
|
|
||||||
|
|
||||||
/* If we created a dummy context, throw it away */
|
/* If we created a dummy context, throw it away */
|
||||||
if (NULL != fake_ctx) WineD3D_ReleaseFakeGLContext(fake_ctx);
|
if (NULL != fake_ctx) WineD3D_ReleaseFakeGLContext(fake_ctx);
|
||||||
|
|
||||||
|
@ -1467,6 +1493,8 @@ 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 */
|
||||||
|
|
||||||
/* 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 == FALSE) {
|
if (This->isGLInfoValid == FALSE) {
|
||||||
/* use the desktop window to fill gl caps */
|
/* use the desktop window to fill gl caps */
|
||||||
|
@ -1474,8 +1502,9 @@ 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,
|
||||||
|
&wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
|
||||||
|
|
||||||
/* ------------------------------------------------
|
/* ------------------------------------------------
|
||||||
The following fields apply to both d3d8 and d3d9
|
The following fields apply to both d3d8 and d3d9
|
||||||
|
@ -1718,19 +1747,16 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
|
||||||
*pCaps->MaxStreams = MAX_STREAMS;
|
*pCaps->MaxStreams = MAX_STREAMS;
|
||||||
*pCaps->MaxStreamStride = 1024;
|
*pCaps->MaxStreamStride = 1024;
|
||||||
|
|
||||||
if (wined3d_settings.vs_mode == VS_HW && wined3d_settings.shader_mode == SHADER_GLSL
|
/* FIXME: the shader mode should be per adapter */
|
||||||
&& DeviceType != WINED3DDEVTYPE_REF) {
|
if (wined3d_settings.vs_selected_mode == SHADER_GLSL) {
|
||||||
*pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
|
*pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
|
||||||
TRACE_(d3d_caps)("Hardware vertex shader versions 2.0+ enabled\n");
|
TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n");
|
||||||
} else if (wined3d_settings.vs_mode == VS_HW
|
} else if (wined3d_settings.vs_selected_mode == SHADER_ARB) {
|
||||||
&& wined3d_settings.shader_mode == SHADER_ARB
|
|
||||||
&& DeviceType != WINED3DDEVTYPE_REF) {
|
|
||||||
*pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
|
*pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
|
||||||
TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled\n");
|
TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
|
||||||
} else if (wined3d_settings.vs_mode == VS_SW || DeviceType == WINED3DDEVTYPE_REF) {
|
} else if (wined3d_settings.vs_selected_mode == SHADER_SW) {
|
||||||
/* FIXME: Change the following line (when needed) to reflect the reported software vertex shader version implemented */
|
*pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
|
||||||
*pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
|
TRACE_(d3d_caps)("Software vertex shader version 3.0 enabled\n");
|
||||||
TRACE_(d3d_caps)("Software vertex shader version 1.1 enabled\n");
|
|
||||||
} else {
|
} else {
|
||||||
*pCaps->VertexShaderVersion = 0;
|
*pCaps->VertexShaderVersion = 0;
|
||||||
TRACE_(d3d_caps)("Vertex shader functionality not available\n");
|
TRACE_(d3d_caps)("Vertex shader functionality not available\n");
|
||||||
|
@ -1742,23 +1768,21 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
|
||||||
*pCaps->MaxVertexShaderConst = WINED3D_VSHADER_MAX_CONSTANTS;
|
*pCaps->MaxVertexShaderConst = WINED3D_VSHADER_MAX_CONSTANTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wined3d_settings.ps_mode == PS_HW && wined3d_settings.shader_mode == SHADER_GLSL
|
/* FIXME: the shader ode should be per adapter */
|
||||||
&& DeviceType != WINED3DDEVTYPE_REF) {
|
if (wined3d_settings.ps_selected_mode == SHADER_GLSL) {
|
||||||
*pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
|
*pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
|
||||||
/* 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 versions 2.0+ enabled\n");
|
TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n");
|
||||||
} else if (wined3d_settings.ps_mode == PS_HW
|
} else if (wined3d_settings.ps_selected_mode == SHADER_ARB) {
|
||||||
&& wined3d_settings.shader_mode == SHADER_ARB
|
|
||||||
&& DeviceType != WINED3DDEVTYPE_REF) {
|
|
||||||
*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\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 1.4 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_mode == PS_SW || DeviceType == WINED3DDEVTYPE_REF) {
|
} else if (wined3d_settings.ps_selected_mode = SHADER_SW) {
|
||||||
*pCaps->PixelShaderVersion = D3DPS_VERSION(1,4);
|
*pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
|
||||||
*pCaps->PixelShader1xMaxValue = 1.0;
|
*pCaps->PixelShader1xMaxValue = 1.0;
|
||||||
TRACE_(d3d_caps)("Software pixel shader version 1.4 enabled\n"); */
|
TRACE_(d3d_caps)("Software pixel shader version 3.0 enabled\n"); */
|
||||||
} else {
|
} else {
|
||||||
*pCaps->PixelShaderVersion = 0;
|
*pCaps->PixelShaderVersion = 0;
|
||||||
*pCaps->PixelShader1xMaxValue = 0.0;
|
*pCaps->PixelShader1xMaxValue = 0.0;
|
||||||
|
@ -1865,8 +1889,11 @@ 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 */
|
||||||
IWineD3DImpl_FillGLCaps(&This->gl_info, IWineD3DImpl_GetAdapterDisplay(iface, Adapter));
|
IWineD3DImpl_FillGLCaps(&This->gl_info, IWineD3DImpl_GetAdapterDisplay(iface, Adapter));
|
||||||
LEAVE_GL();
|
LEAVE_GL();
|
||||||
|
select_shader_mode(&This->gl_info, DeviceType,
|
||||||
|
&wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
|
||||||
|
|
||||||
/* set the state of the device to valid */
|
/* set the state of the device to valid */
|
||||||
object->state = WINED3D_OK;
|
object->state = WINED3D_OK;
|
||||||
|
|
|
@ -1962,7 +1962,9 @@ UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idx
|
||||||
TRACE("Loaded arrays\n");
|
TRACE("Loaded arrays\n");
|
||||||
|
|
||||||
/* Bind the correct GLSL shader program based on the currently set vertex & pixel shaders. */
|
/* Bind the correct GLSL shader program based on the currently set vertex & pixel shaders. */
|
||||||
if (wined3d_settings.shader_mode == SHADER_GLSL) {
|
if (wined3d_settings.vs_selected_mode == SHADER_GLSL ||
|
||||||
|
wined3d_settings.ps_selected_mode == SHADER_GLSL) {
|
||||||
|
|
||||||
set_glsl_shader_program(iface);
|
set_glsl_shader_program(iface);
|
||||||
/* Start using this program ID (if it's 0, there is no shader program to use, so
|
/* Start using this program ID (if it's 0, there is no shader program to use, so
|
||||||
* glUseProgramObjectARB(0) will disable the use of any shaders) */
|
* glUseProgramObjectARB(0) will disable the use of any shaders) */
|
||||||
|
@ -1977,7 +1979,7 @@ UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idx
|
||||||
|
|
||||||
TRACE("Using vertex shader\n");
|
TRACE("Using vertex shader\n");
|
||||||
|
|
||||||
if (wined3d_settings.shader_mode == SHADER_ARB) {
|
if (wined3d_settings.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));
|
||||||
|
@ -1995,7 +1997,7 @@ UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idx
|
||||||
|
|
||||||
TRACE("Using pixel shader\n");
|
TRACE("Using pixel shader\n");
|
||||||
|
|
||||||
if (wined3d_settings.shader_mode == SHADER_ARB) {
|
if (wined3d_settings.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));
|
||||||
|
@ -2010,10 +2012,10 @@ UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idx
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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.shader_mode == SHADER_GLSL)
|
if (wined3d_settings.vs_selected_mode == SHADER_GLSL || wined3d_settings.ps_selected_mode == SHADER_GLSL)
|
||||||
shader_glsl_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
|
shader_glsl_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
|
||||||
else if (wined3d_settings.shader_mode == SHADER_ARB)
|
else if (wined3d_settings.vs_selected_mode== SHADER_ARB || wined3d_settings.ps_selected_mode == SHADER_ARB)
|
||||||
shader_arb_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
|
shader_arb_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
|
||||||
|
|
||||||
|
|
||||||
/* DirectX colours are in a different format to opengl colours
|
/* DirectX colours are in a different format to opengl colours
|
||||||
|
@ -2046,12 +2048,12 @@ UINT numberOfvertices, UINT numberOfIndicies, GLenum glPrimType, const void *idx
|
||||||
checkGLcall("glDisableVertexAttribArrayARB(reg);");
|
checkGLcall("glDisableVertexAttribArrayARB(reg);");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wined3d_settings.shader_mode == SHADER_ARB)
|
if (wined3d_settings.vs_selected_mode == SHADER_ARB)
|
||||||
glDisable(GL_VERTEX_PROGRAM_ARB);
|
glDisable(GL_VERTEX_PROGRAM_ARB);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cleanup fragment program */
|
/* Cleanup fragment program */
|
||||||
if (usePixelShaderFunction && wined3d_settings.shader_mode == SHADER_ARB) {
|
if (usePixelShaderFunction && wined3d_settings.ps_selected_mode == SHADER_ARB) {
|
||||||
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2278,19 +2280,15 @@ void drawPrimitive(IWineD3DDevice *iface,
|
||||||
int useHW = FALSE, i;
|
int useHW = FALSE, i;
|
||||||
BOOL fixup = FALSE;
|
BOOL fixup = FALSE;
|
||||||
|
|
||||||
if (This->stateBlock->vertexShader != NULL && wined3d_settings.vs_mode != VS_NONE
|
/* Shaders can be implemented using ARB_PROGRAM, GLSL, or software -
|
||||||
&&((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.function != NULL
|
* here simply check whether a shader was set, or the user disabled shaders */
|
||||||
&& GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
|
if (wined3d_settings.vs_selected_mode != SHADER_NONE && This->stateBlock->vertexShader &&
|
||||||
|
((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.function != NULL)
|
||||||
useVertexShaderFunction = TRUE;
|
useVertexShaderFunction = TRUE;
|
||||||
} else {
|
|
||||||
useVertexShaderFunction = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wined3d_settings.ps_mode != PS_NONE && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)
|
if (wined3d_settings.ps_selected_mode != SHADER_NONE && This->stateBlock->pixelShader &&
|
||||||
&& This->stateBlock->pixelShader
|
((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function)
|
||||||
&& ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function) {
|
|
||||||
usePixelShaderFunction = TRUE;
|
usePixelShaderFunction = TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
if (This->stateBlock->vertexDecl == NULL) {
|
if (This->stateBlock->vertexDecl == NULL) {
|
||||||
/* Work out what the FVF should look like */
|
/* Work out what the FVF should look like */
|
||||||
|
|
|
@ -73,7 +73,7 @@ static ULONG WINAPI IWineD3DPixelShaderImpl_Release(IWineD3DPixelShader *iface)
|
||||||
ref = InterlockedDecrement(&This->ref);
|
ref = InterlockedDecrement(&This->ref);
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
HeapFree(GetProcessHeap(), 0, This);
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
if (wined3d_settings.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
||||||
/* If this shader is still attached to a program, GL will perform a lazy delete */
|
/* If this shader is still attached to a program, GL will perform a lazy delete */
|
||||||
TRACE("Deleting shader object %u\n", This->baseShader.prgId);
|
TRACE("Deleting shader object %u\n", This->baseShader.prgId);
|
||||||
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
|
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
|
||||||
|
@ -829,7 +829,7 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
|
||||||
buffer.bsize = 0;
|
buffer.bsize = 0;
|
||||||
buffer.lineNo = 0;
|
buffer.lineNo = 0;
|
||||||
|
|
||||||
if (wined3d_settings.shader_mode == SHADER_GLSL) {
|
if (This->baseShader.shader_mode == SHADER_GLSL) {
|
||||||
|
|
||||||
/* Create the hw GLSL shader object and assign it as the baseShader.prgId */
|
/* Create the hw GLSL shader object and assign it as the baseShader.prgId */
|
||||||
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
|
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
|
||||||
|
@ -857,7 +857,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.shader_mode == SHADER_ARB) {
|
} else if (wined3d_settings.ps_selected_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");
|
||||||
|
|
||||||
|
@ -913,7 +913,8 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
|
||||||
pshader_set_limits(This);
|
pshader_set_limits(This);
|
||||||
|
|
||||||
/* Generate HW shader in needed */
|
/* Generate HW shader in needed */
|
||||||
if (NULL != pFunction && wined3d_settings.vs_mode == VS_HW) {
|
This->baseShader.shader_mode = wined3d_settings.ps_selected_mode;
|
||||||
|
if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW) {
|
||||||
TRACE("(%p) : Generating hardware program\n", This);
|
TRACE("(%p) : Generating hardware program\n", This);
|
||||||
IWineD3DPixelShaderImpl_GenerateShader(iface, pFunction);
|
IWineD3DPixelShaderImpl_GenerateShader(iface, pFunction);
|
||||||
}
|
}
|
||||||
|
|
|
@ -644,7 +644,7 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
|
||||||
buffer.bsize = 0;
|
buffer.bsize = 0;
|
||||||
buffer.lineNo = 0;
|
buffer.lineNo = 0;
|
||||||
|
|
||||||
if (wined3d_settings.shader_mode == SHADER_GLSL) {
|
if (This->baseShader.shader_mode == SHADER_GLSL) {
|
||||||
|
|
||||||
/* Create the hw GLSL shader program and assign it as the baseShader.prgId */
|
/* Create the hw GLSL shader program and assign it as the baseShader.prgId */
|
||||||
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
|
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
|
||||||
|
@ -669,7 +669,7 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
|
||||||
/* Store the shader object */
|
/* Store the shader object */
|
||||||
This->baseShader.prgId = shader_obj;
|
This->baseShader.prgId = shader_obj;
|
||||||
|
|
||||||
} else if (wined3d_settings.shader_mode == SHADER_ARB) {
|
} else if (This->baseShader.shader_mode == SHADER_ARB) {
|
||||||
|
|
||||||
/* Create the hw ARB shader */
|
/* Create the hw ARB shader */
|
||||||
shader_addline(&buffer, "!!ARBvp1.0\n");
|
shader_addline(&buffer, "!!ARBvp1.0\n");
|
||||||
|
@ -990,7 +990,7 @@ static ULONG WINAPI IWineD3DVertexShaderImpl_Release(IWineD3DVertexShader *iface
|
||||||
ref = InterlockedDecrement(&This->ref);
|
ref = InterlockedDecrement(&This->ref);
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
if (This->vertexDeclaration) IWineD3DVertexDeclaration_Release(This->vertexDeclaration);
|
if (This->vertexDeclaration) IWineD3DVertexDeclaration_Release(This->vertexDeclaration);
|
||||||
if (wined3d_settings.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
|
||||||
/* If this shader is still attached to a program, GL will perform a lazy delete */
|
/* If this shader is still attached to a program, GL will perform a lazy delete */
|
||||||
TRACE("Deleting shader object %u\n", This->baseShader.prgId);
|
TRACE("Deleting shader object %u\n", This->baseShader.prgId);
|
||||||
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
|
GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
|
||||||
|
@ -1055,7 +1055,8 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
|
||||||
vshader_set_limits(This);
|
vshader_set_limits(This);
|
||||||
|
|
||||||
/* Generate HW shader in needed */
|
/* Generate HW shader in needed */
|
||||||
if (NULL != pFunction && wined3d_settings.vs_mode == VS_HW)
|
This->baseShader.shader_mode = wined3d_settings.vs_selected_mode;
|
||||||
|
if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW)
|
||||||
IWineD3DVertexShaderImpl_GenerateShader(iface, pFunction);
|
IWineD3DVertexShaderImpl_GenerateShader(iface, pFunction);
|
||||||
|
|
||||||
/* copy the function ... because it will certainly be released by application */
|
/* copy the function ... because it will certainly be released by application */
|
||||||
|
@ -1065,6 +1066,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
|
||||||
} else {
|
} else {
|
||||||
This->baseShader.function = NULL;
|
This->baseShader.function = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return WINED3D_OK;
|
return WINED3D_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,6 +136,7 @@ WINED3DGLTYPE static const glTypeLookup[D3DDECLTYPE_UNUSED] = {
|
||||||
#define SHADER_SW 0
|
#define SHADER_SW 0
|
||||||
#define SHADER_ARB 1
|
#define SHADER_ARB 1
|
||||||
#define SHADER_GLSL 2
|
#define SHADER_GLSL 2
|
||||||
|
#define SHADER_NONE 3
|
||||||
|
|
||||||
typedef struct wined3d_settings_s {
|
typedef struct wined3d_settings_s {
|
||||||
/* vertex and pixel shader modes */
|
/* vertex and pixel shader modes */
|
||||||
|
@ -146,7 +147,8 @@ 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 shader_mode;
|
int vs_selected_mode;
|
||||||
|
int ps_selected_mode;
|
||||||
/* nonpower 2 function */
|
/* nonpower 2 function */
|
||||||
int nonpower2_mode;
|
int nonpower2_mode;
|
||||||
} wined3d_settings_t;
|
} wined3d_settings_t;
|
||||||
|
@ -1460,6 +1462,10 @@ typedef struct IWineD3DBaseShaderClass
|
||||||
CONST DWORD *function;
|
CONST DWORD *function;
|
||||||
UINT functionLength;
|
UINT functionLength;
|
||||||
GLuint prgId;
|
GLuint prgId;
|
||||||
|
|
||||||
|
/* Type of shader backend */
|
||||||
|
int shader_mode;
|
||||||
|
|
||||||
} IWineD3DBaseShaderClass;
|
} IWineD3DBaseShaderClass;
|
||||||
|
|
||||||
typedef struct IWineD3DBaseShaderImpl {
|
typedef struct IWineD3DBaseShaderImpl {
|
||||||
|
|
Loading…
Reference in New Issue