Stefan Dösinger : wined3d: Only generate the clipplane emulation KIL if a clipplane is used.

Alexandre Julliard julliard at winehq.org
Tue Sep 8 08:54:14 CDT 2009


Module: wine
Branch: master
Commit: d6547c535b7d7142841f6ab5a580abba27198a18
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d6547c535b7d7142841f6ab5a580abba27198a18

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sun Aug 30 21:02:05 2009 +0200

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 a26950c..848d83d 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 3c25ebe..ff81078 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 {




More information about the wine-cvs mailing list