wined3d: Set ffp caps in the ffp backend, not the shader backend.

This commit is contained in:
Stefan Dösinger 2008-07-03 14:36:18 -05:00 committed by Alexandre Julliard
parent c48195e417
commit e4078fb0ba
6 changed files with 140 additions and 131 deletions

View File

@ -972,8 +972,56 @@ static void atifs_enable(IWineD3DDevice *iface, BOOL enable) {
}
}
static void atifs_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *caps) {
caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE |
WINED3DTEXOPCAPS_SELECTARG1 |
WINED3DTEXOPCAPS_SELECTARG2 |
WINED3DTEXOPCAPS_MODULATE4X |
WINED3DTEXOPCAPS_MODULATE2X |
WINED3DTEXOPCAPS_MODULATE |
WINED3DTEXOPCAPS_ADDSIGNED2X |
WINED3DTEXOPCAPS_ADDSIGNED |
WINED3DTEXOPCAPS_ADD |
WINED3DTEXOPCAPS_SUBTRACT |
WINED3DTEXOPCAPS_ADDSMOOTH |
WINED3DTEXOPCAPS_BLENDCURRENTALPHA |
WINED3DTEXOPCAPS_BLENDFACTORALPHA |
WINED3DTEXOPCAPS_BLENDTEXTUREALPHA |
WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM |
WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |
WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
WINED3DTEXOPCAPS_DOTPRODUCT3 |
WINED3DTEXOPCAPS_MULTIPLYADD |
WINED3DTEXOPCAPS_LERP |
WINED3DTEXOPCAPS_BUMPENVMAP;
/* TODO: Implement WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
and WINED3DTEXOPCAPS_PREMODULATE */
/* GL_ATI_fragment_shader always supports 6 textures, which was the limit on r200 cards
* which this extension is exclusively focused on(later cards have GL_ARB_fragment_program).
* If the current card has more than 8 fixed function textures in OpenGL's regular fixed
* function pipeline then the ATI_fragment_shader backend imposes a stricter limit. This
* shouldn't be too hard since Nvidia cards have a limit of 4 textures with the default ffp
* pipeline, and almost all games are happy with that. We can however support up to 8
* texture stages because we have a 2nd pass limit of 8 instructions, and per stage we use
* only 1 instruction.
*
* The proper fix for this is not to use GL_ATI_fragment_shader on cards newer than the
* r200 series and use an ARB or GLSL shader instead
*/
caps->MaxTextureBlendStages = 8;
caps->MaxSimultaneousTextures = 6;
caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP;
}
const struct fragment_pipeline atifs_fragment_pipeline = {
atifs_enable,
atifs_get_caps,
atifs_fragmentstate_template
};
@ -1055,54 +1103,6 @@ static BOOL shader_atifs_dirty_const(IWineD3DDevice *iface) {
static void shader_atifs_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *caps) {
arb_program_shader_backend.shader_get_caps(devtype, gl_info, caps);
caps->TextureOpCaps = WINED3DTEXOPCAPS_DISABLE |
WINED3DTEXOPCAPS_SELECTARG1 |
WINED3DTEXOPCAPS_SELECTARG2 |
WINED3DTEXOPCAPS_MODULATE4X |
WINED3DTEXOPCAPS_MODULATE2X |
WINED3DTEXOPCAPS_MODULATE |
WINED3DTEXOPCAPS_ADDSIGNED2X |
WINED3DTEXOPCAPS_ADDSIGNED |
WINED3DTEXOPCAPS_ADD |
WINED3DTEXOPCAPS_SUBTRACT |
WINED3DTEXOPCAPS_ADDSMOOTH |
WINED3DTEXOPCAPS_BLENDCURRENTALPHA |
WINED3DTEXOPCAPS_BLENDFACTORALPHA |
WINED3DTEXOPCAPS_BLENDTEXTUREALPHA |
WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM |
WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA |
WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
WINED3DTEXOPCAPS_DOTPRODUCT3 |
WINED3DTEXOPCAPS_MULTIPLYADD |
WINED3DTEXOPCAPS_LERP |
WINED3DTEXOPCAPS_BUMPENVMAP;
/* TODO: Implement WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
and WINED3DTEXOPCAPS_PREMODULATE */
/* GL_ATI_fragment_shader only supports up to 6 textures, which was the limit on r200 cards
* which this extension is exclusively focused on(later cards have GL_ARB_fragment_program).
* If the current card has more than 8 fixed function textures in OpenGL's regular fixed
* function pipeline then the ATI_fragment_shader backend imposes a stricter limit. This
* shouldn't be too hard since Nvidia cards have a limit of 4 textures with the default ffp
* pipeline, and almost all games are happy with that. We can however support up to 8
* texture stages because we have a 2nd pass limit of 8 instructions, and per stage we use
* only 1 instruction.
*
* The proper fix for this is not to use GL_ATI_fragment_shader on cards newer than the
* r200 series and use an ARB or GLSL shader instead
*/
if(caps->MaxSimultaneousTextures > 6) {
WARN("OpenGL fixed function supports %d simultaneous textures,\n", caps->MaxSimultaneousTextures);
WARN("but GL_ATI_fragment_shader limits this to 6\n");
caps->MaxSimultaneousTextures = 6;
}
caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP;
}
static void shader_atifs_generate_pshader(IWineD3DPixelShader *iface, SHADER_BUFFER *buffer) {

View File

@ -1108,78 +1108,10 @@ static void shader_none_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF
#define GLINFO_LOCATION (*gl_info)
static void shader_none_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *pCaps) {
pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD |
WINED3DTEXOPCAPS_ADDSIGNED |
WINED3DTEXOPCAPS_ADDSIGNED2X |
WINED3DTEXOPCAPS_MODULATE |
WINED3DTEXOPCAPS_MODULATE2X |
WINED3DTEXOPCAPS_MODULATE4X |
WINED3DTEXOPCAPS_SELECTARG1 |
WINED3DTEXOPCAPS_SELECTARG2 |
WINED3DTEXOPCAPS_DISABLE;
if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
WINED3DTEXOPCAPS_BLENDTEXTUREALPHA |
WINED3DTEXOPCAPS_BLENDFACTORALPHA |
WINED3DTEXOPCAPS_BLENDCURRENTALPHA |
WINED3DTEXOPCAPS_LERP |
WINED3DTEXOPCAPS_SUBTRACT;
}
if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH |
WINED3DTEXOPCAPS_MULTIPLYADD |
WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
}
if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA;
}
if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
} else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
/* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
* not support 3D textures. This asks for trouble if an app uses both bump mapping
* and 3D textures. It also allows us to keep the code simpler by having texture
* shaders constantly enabled.
*/
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
/* TODO: Luminance bump map? */
}
#if 0
/* FIXME: Add
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
WINED3DTEXOPCAPS_PREMODULATE */
#endif
pCaps->MaxTextureBlendStages = GL_LIMITS(texture_stages);
pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
/* Set the shader caps to 0 for the none shader backend */
pCaps->VertexShaderVersion = 0;
pCaps->PixelShaderVersion = 0;
pCaps->PixelShader1xMaxValue = 0.0;
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP;
}
/* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
#if 0
if (GL_SUPPORT(NV_REGISTER_COMBINERS2))
pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_PERSTAGECONSTANT;
#endif
}
#undef GLINFO_LOCATION

View File

@ -2913,7 +2913,9 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
int vs_selected_mode;
int ps_selected_mode;
struct shader_caps shader_caps;
struct fragment_caps fragment_caps;
const shader_backend_t *shader_backend;
const struct fragment_pipeline *frag_pipeline = NULL;
TRACE_(d3d_caps)("(%p)->(Adptr:%d, DevType: %x, pCaps: %p)\n", This, Adapter, DeviceType, pCaps);
@ -3272,8 +3274,12 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
shader_backend = select_shader_backend(Adapter, DeviceType);
shader_backend->shader_get_caps(DeviceType, &GLINFO_LOCATION, &shader_caps);
memset(&fragment_caps, 0, sizeof(fragment_caps));
frag_pipeline = select_fragment_implementation(Adapter, DeviceType);
frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &fragment_caps);
/* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
pCaps->PrimitiveMiscCaps |= shader_caps.PrimitiveMiscCaps;
pCaps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
/* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
* Ignore shader model capabilities if disabled in config
@ -3296,9 +3302,10 @@ static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter,
pCaps->PixelShader1xMaxValue = shader_caps.PixelShader1xMaxValue;
}
pCaps->TextureOpCaps = shader_caps.TextureOpCaps;
pCaps->MaxTextureBlendStages = shader_caps.MaxTextureBlendStages;
pCaps->MaxSimultaneousTextures = shader_caps.MaxSimultaneousTextures;
pCaps->TextureOpCaps = fragment_caps.TextureOpCaps;
pCaps->MaxTextureBlendStages = fragment_caps.MaxTextureBlendStages;
pCaps->MaxSimultaneousTextures = fragment_caps.MaxSimultaneousTextures;
pCaps->VS20Caps = shader_caps.VS20Caps;
pCaps->MaxVShaderInstructionsExecuted = shader_caps.MaxVShaderInstructionsExecuted;
pCaps->MaxVertexShader30InstructionSlots= shader_caps.MaxVertexShader30InstructionSlots;

View File

@ -3649,11 +3649,6 @@ static void shader_glsl_generate_vshader(IWineD3DVertexShader *iface, SHADER_BUF
}
static void shader_glsl_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct shader_caps *pCaps) {
/* We don't have a GLSL fixed function pipeline yet, so let the none backend set its caps,
* then overwrite the shader specific ones
*/
none_shader_backend.shader_get_caps(devtype, gl_info, pCaps);
/* 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.

View File

@ -4463,10 +4463,82 @@ static void nvts_enable(IWineD3DDevice *iface, BOOL enable) {
}
}
}
static void ffp_fragment_get_caps(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *pCaps) {
pCaps->TextureOpCaps = WINED3DTEXOPCAPS_ADD |
WINED3DTEXOPCAPS_ADDSIGNED |
WINED3DTEXOPCAPS_ADDSIGNED2X |
WINED3DTEXOPCAPS_MODULATE |
WINED3DTEXOPCAPS_MODULATE2X |
WINED3DTEXOPCAPS_MODULATE4X |
WINED3DTEXOPCAPS_SELECTARG1 |
WINED3DTEXOPCAPS_SELECTARG2 |
WINED3DTEXOPCAPS_DISABLE;
if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE) ||
GL_SUPPORT(EXT_TEXTURE_ENV_COMBINE) ||
GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BLENDDIFFUSEALPHA |
WINED3DTEXOPCAPS_BLENDTEXTUREALPHA |
WINED3DTEXOPCAPS_BLENDFACTORALPHA |
WINED3DTEXOPCAPS_BLENDCURRENTALPHA |
WINED3DTEXOPCAPS_LERP |
WINED3DTEXOPCAPS_SUBTRACT;
}
if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3) ||
GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) {
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_ADDSMOOTH |
WINED3DTEXOPCAPS_MULTIPLYADD |
WINED3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR |
WINED3DTEXOPCAPS_MODULATECOLOR_ADDALPHA |
WINED3DTEXOPCAPS_BLENDTEXTUREALPHAPM;
}
if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3))
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_DOTPRODUCT3;
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_MODULATEINVALPHA_ADDCOLOR |
WINED3DTEXOPCAPS_MODULATEINVCOLOR_ADDALPHA;
}
if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) {
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
} else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
/* Bump mapping is supported already in NV_TEXTURE_SHADER, but that extension does
* not support 3D textures. This asks for trouble if an app uses both bump mapping
* and 3D textures. It also allows us to keep the code simpler by having texture
* shaders constantly enabled.
*/
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAP;
/* TODO: Luminance bump map? */
}
#if 0
/* FIXME: Add
pCaps->TextureOpCaps |= WINED3DTEXOPCAPS_BUMPENVMAPLUMINANCE
WINED3DTEXOPCAPS_PREMODULATE */
#endif
pCaps->MaxTextureBlendStages = GL_LIMITS(texture_stages);
pCaps->MaxSimultaneousTextures = GL_LIMITS(textures);
if (GL_SUPPORT(NV_REGISTER_COMBINERS)) {
pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_TSSARGTEMP;
}
/* The caps below can be supported but aren't handled yet in utils.c 'd3dta_to_combiner_input', disable them until support is fixed */
#if 0
if (GL_SUPPORT(NV_REGISTER_COMBINERS2))
pCaps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_PERSTAGECONSTANT;
#endif
}
#undef GLINFO_LOCATION
const struct fragment_pipeline ffp_fragment_pipeline = {
nvts_enable,
ffp_fragment_get_caps,
ffp_fragmentstate_template
};

View File

@ -218,12 +218,6 @@ typedef struct SHADER_BUFFER {
} SHADER_BUFFER;
struct shader_caps {
DWORD PrimitiveMiscCaps;
DWORD TextureOpCaps;
DWORD MaxTextureBlendStages;
DWORD MaxSimultaneousTextures;
DWORD VertexShaderVersion;
DWORD MaxVertexShaderConst;
@ -546,8 +540,17 @@ struct StateEntryTemplate
struct StateEntry content;
};
struct fragment_caps {
DWORD PrimitiveMiscCaps;
DWORD TextureOpCaps;
DWORD MaxTextureBlendStages;
DWORD MaxSimultaneousTextures;
};
struct fragment_pipeline {
void (*enable_extension)(IWineD3DDevice *iface, BOOL enable);
void (*get_caps)(WINED3DDEVTYPE devtype, WineD3D_GL_Info *gl_info, struct fragment_caps *caps);
const struct StateEntryTemplate *states;
};