From d6547c535b7d7142841f6ab5a580abba27198a18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sun, 30 Aug 2009 21:02:05 +0200 Subject: [PATCH] wined3d: Only generate the clipplane emulation KIL if a clipplane is used. The KIL is quite expensive because it forces drivers to disable early Z discard. It is cheaper to generate and switch between two shaders. --- dlls/wined3d/arb_program_shader.c | 19 +++++++++++++++++-- dlls/wined3d/utils.c | 6 ++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index a26950cd169..848d83d886b 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -125,7 +125,8 @@ struct arb_ps_np2fixup_info struct arb_ps_compile_args { struct ps_compile_args super; - DWORD bools; /* WORD is enough, use DWORD for alignment */ + WORD bools; + WORD clip; /* only a boolean, use a WORD for alignment */ unsigned char loop_ctrl[MAX_CONST_I][3]; }; @@ -3496,7 +3497,7 @@ static GLuint shader_arb_generate_pshader(IWineD3DPixelShaderImpl *This, struct next_local += fixup->super.num_consts; } - if (shader_priv->clipplane_emulation != ~0U) + if (shader_priv->clipplane_emulation != ~0U && args->clip) { shader_addline(buffer, "KIL fragment.texcoord[%u];\n", shader_priv->clipplane_emulation); } @@ -4128,6 +4129,20 @@ static inline void find_arb_ps_compile_args(IWineD3DPixelShaderImpl *shader, IWi if(stateblock->pixelShaderConstantB[i]) args->bools |= ( 1 << i); } + /* Only enable the clip plane emulation KIL if at least one clipplane is enabled. The KIL instruction + * is quite expensive because it forces the driver to disable early Z discards. It is cheaper to + * duplicate the shader than have a no-op KIL instruction in every shader + */ + if((!((IWineD3DDeviceImpl *) shader->baseShader.device)->vs_clipping) && use_vs(stateblock) && + stateblock->renderState[WINED3DRS_CLIPPING] && stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) + { + args->clip = 1; + } + else + { + args->clip = 0; + } + /* Skip if unused or local, or supported natively */ int_skip = ~shader->baseShader.reg_maps.integer_constants | shader->baseShader.reg_maps.local_int_consts; if(int_skip == 0xffff || GL_SUPPORT(NV_FRAGMENT_PROGRAM_OPTION)) diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 3c25ebeb3e0..ff81078949b 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -2531,9 +2531,11 @@ void gen_ffp_frag_op(IWineD3DStateBlockImpl *stateblock, struct ffp_frag_setting } else { settings->sRGB_write = 0; } - if(device->vs_clipping || !use_vs(stateblock)) { + if(device->vs_clipping || !use_vs(stateblock) || !stateblock->renderState[WINED3DRS_CLIPPING] || + !stateblock->renderState[WINED3DRS_CLIPPLANEENABLE]) { /* No need to emulate clipplanes if GL supports native vertex shader clipping or if - * the fixed function vertex pipeline is used(which always supports clipplanes) + * the fixed function vertex pipeline is used(which always supports clipplanes), or + * if no clipplane is enabled */ settings->emul_clipplanes = 0; } else {