[PATCH xf86-video-ati 2/2] Keep track of damage event related flushes per-client

Deucher, Alexander Alexander.Deucher at amd.com
Mon Aug 1 15:56:10 UTC 2016


> -----Original Message-----
> From: amd-gfx [mailto:amd-gfx-bounces at lists.freedesktop.org] On Behalf
> Of Michel Dänzer
> Sent: Monday, August 01, 2016 5:59 AM
> To: amd-gfx at lists.freedesktop.org
> Subject: [PATCH xf86-video-ati 2/2] Keep track of damage event related
> flushes per-client
> 
> From: Michel Dänzer <michel.daenzer at amd.com>
> 
> This further reduces the compositing slowdown due to flushing overhead,
> by only flushing when the X server actually sends XDamageNotify events
> to a client, and there hasn't been a flush yet in the meantime.
> 
> Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>

For the series:
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
> 
> This patch can't have an effect without a corresponding xserver patch
> which passes the ClientPtr to the FlushCallback, so I'll only push this
> one once the xserver patch has landed.
> 
>  src/radeon.h     |  5 ++++-
>  src/radeon_kms.c | 34 ++++++++++++++++++++++++++++------
>  2 files changed, 32 insertions(+), 7 deletions(-)
> 
> diff --git a/src/radeon.h b/src/radeon.h
> index 25ff61c..b119241 100644
> --- a/src/radeon.h
> +++ b/src/radeon.h
> @@ -448,6 +448,10 @@ struct radeon_accel_state {
>      Bool              force;
>  };
> 
> +struct radeon_client_priv {
> +    uint_fast32_t     needs_flush[0];
> +};
> +
>  typedef struct {
>      EntityInfoPtr     pEnt;
>      pciVideoPtr       PciInfo;
> @@ -474,7 +478,6 @@ typedef struct {
>      Bool              allowColorTiling;
>      Bool              allowColorTiling2D;
>      int               callback_event_type;
> -    uint_fast32_t     callback_needs_flush;
>      uint_fast32_t     gpu_flushed;
>      uint_fast32_t     gpu_synced;
>      struct radeon_accel_state *accel_state;
> diff --git a/src/radeon_kms.c b/src/radeon_kms.c
> index da11358..7ede3a1 100644
> --- a/src/radeon_kms.c
> +++ b/src/radeon_kms.c
> @@ -40,6 +40,7 @@
> 
>  #include "radeon_version.h"
>  #include "shadow.h"
> +#include <xf86Priv.h>
> 
>  #include "atipciids.h"
> 
> @@ -59,6 +60,8 @@
>  #include "radeon_cs_gem.h"
>  #include "radeon_vbo.h"
> 
> +static DevPrivateKeyRec radeon_client_private_key;
> +
>  extern SymTabRec RADEONChipsets[];
>  static Bool radeon_setup_kernel_mem(ScreenPtr pScreen);
> 
> @@ -241,9 +244,9 @@ radeonUpdatePacked(ScreenPtr pScreen,
> shadowBufPtr pBuf)
>  }
> 
>  static Bool
> -callback_needs_flush(RADEONInfoPtr info)
> +callback_needs_flush(RADEONInfoPtr info, uint_fast32_t needs_flush)
>  {
> -    return (int)(info->callback_needs_flush - info->gpu_flushed) > 0;
> +    return (int)(needs_flush - info->gpu_flushed) > 0;
>  }
> 
>  static void
> @@ -251,21 +254,28 @@ radeon_event_callback(CallbackListPtr *list,
>  		      pointer user_data, pointer call_data)
>  {
>      EventInfoRec *eventinfo = call_data;
> +    struct radeon_client_priv *client_priv =
> +	dixLookupPrivate(&eventinfo->client->devPrivates,
> &radeon_client_private_key);
> +    struct radeon_client_priv *server_priv =
> +	dixLookupPrivate(&serverClient->devPrivates,
> &radeon_client_private_key);
>      ScrnInfoPtr pScrn = user_data;
>      RADEONInfoPtr info = RADEONPTR(pScrn);
>      int i;
> 
> -    if (callback_needs_flush(info))
> +    if (callback_needs_flush(info, client_priv->needs_flush[pScrn-
> >scrnIndex]) ||
> +	callback_needs_flush(info, server_priv->needs_flush[pScrn-
> >scrnIndex]))
>  	return;
> 
>      /* Don't let gpu_flushed get too far ahead of callback_needs_flush,
>       * in order to prevent false positives in callback_needs_flush()
>       */
> -    info->callback_needs_flush = info->gpu_flushed;
> +    client_priv->needs_flush[pScrn->scrnIndex] = info->gpu_flushed;
> +    server_priv->needs_flush[pScrn->scrnIndex] = info->gpu_flushed;
> 
>      for (i = 0; i < eventinfo->count; i++) {
>  	if (eventinfo->events[i].u.u.type == info->callback_event_type) {
> -	    info->callback_needs_flush++;
> +	    client_priv->needs_flush[pScrn->scrnIndex]++;
> +	    server_priv->needs_flush[pScrn->scrnIndex]++;
>  	    return;
>  	}
>      }
> @@ -276,9 +286,13 @@ radeon_flush_callback(CallbackListPtr *list,
>  		      pointer user_data, pointer call_data)
>  {
>      ScrnInfoPtr pScrn = user_data;
> +    ClientPtr client = call_data ? call_data : serverClient;
> +    struct radeon_client_priv *client_priv =
> +	dixLookupPrivate(&client->devPrivates,
> &radeon_client_private_key);
>      RADEONInfoPtr info = RADEONPTR(pScrn);
> 
> -    if (pScrn->vtSema && callback_needs_flush(info))
> +    if (pScrn->vtSema &&
> +	callback_needs_flush(info, client_priv->needs_flush[pScrn-
> >scrnIndex]))
>          radeon_cs_flush_indirect(pScrn);
>  }
> 
> @@ -351,6 +365,14 @@ static Bool
> RADEONCreateScreenResources_KMS(ScreenPtr pScreen)
>  	    DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
>  	    return FALSE;
>  	}
> +
> +	if (!dixPrivateKeyRegistered(&radeon_client_private_key) &&
> +	    !dixRegisterPrivateKey(&radeon_client_private_key,
> PRIVATE_CLIENT,
> +				   xf86NumScreens * sizeof(uint_fast32_t))) {
> +	    DeleteCallback(&FlushCallback, radeon_flush_callback, pScrn);
> +	    DeleteCallback(&EventCallback, radeon_event_callback, pScrn);
> +	    return FALSE;
> +	}
>      }
> 
>      return TRUE;
> --
> 2.8.1
> 
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx


More information about the amd-gfx mailing list