From e4078fb0ba183fce2a1e29009607dddd8995d871 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Thu, 3 Jul 2008 14:36:18 -0500 Subject: [PATCH] wined3d: Set ffp caps in the ffp backend, not the shader backend. --- dlls/wined3d/ati_fragment_shader.c | 96 +++++++++++++++++++------------------- dlls/wined3d/baseshader.c | 68 --------------------------- dlls/wined3d/directx.c | 15 ++++-- dlls/wined3d/glsl_shader.c | 5 -- dlls/wined3d/state.c | 72 ++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 15 +++--- 6 files changed, 140 insertions(+), 131 deletions(-) diff --git a/dlls/wined3d/ati_fragment_shader.c b/dlls/wined3d/ati_fragment_shader.c index 10a56a34e65..e4420f13b73 100644 --- a/dlls/wined3d/ati_fragment_shader.c +++ b/dlls/wined3d/ati_fragment_shader.c @@ -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) { diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index a6231f20dca..57fbf626712 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -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 diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 1918a448625..9992ee24ea3 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -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; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 100f3491847..da13d1d99a0 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -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. diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 627a88f8ddb..0ea627c7cf1 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -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 }; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index ec43fec97ce..327a14f6d9c 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -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; }; -- 2.11.4.GIT