mirror of
https://github.com/X11Libre/xf86-video-amdgpu.git
synced 2026-03-24 01:24:31 +00:00
Keep track of damage event related flushes per-client
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. (Ported from radeon commit 121a6de72da5fcf9a32408eff36b2235f3dfbcfe) Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Michel Dänzer
parent
58773d1945
commit
c7d27c94cb
@@ -185,6 +185,10 @@ struct amdgpu_buffer {
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct amdgpu_client_priv {
|
||||
uint_fast32_t needs_flush;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
EntityInfoPtr pEnt;
|
||||
pciVideoPtr PciInfo;
|
||||
@@ -210,7 +214,6 @@ typedef struct {
|
||||
/* accel */
|
||||
PixmapPtr fbcon_pixmap;
|
||||
int callback_event_type;
|
||||
uint_fast32_t callback_needs_flush;
|
||||
uint_fast32_t gpu_flushed;
|
||||
uint_fast32_t gpu_synced;
|
||||
Bool use_glamor;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "amdgpu_version.h"
|
||||
#include "shadow.h"
|
||||
#include <xf86Priv.h>
|
||||
|
||||
#include "amdpciids.h"
|
||||
|
||||
@@ -58,6 +59,8 @@
|
||||
|
||||
#include <gbm.h>
|
||||
|
||||
static DevScreenPrivateKeyRec amdgpu_client_private_key;
|
||||
|
||||
extern SymTabRec AMDGPUChipsets[];
|
||||
static Bool amdgpu_setup_kernel_mem(ScreenPtr pScreen);
|
||||
|
||||
@@ -166,9 +169,9 @@ amdgpuUpdatePacked(ScreenPtr pScreen, shadowBufPtr pBuf)
|
||||
}
|
||||
|
||||
static Bool
|
||||
callback_needs_flush(AMDGPUInfoPtr info)
|
||||
callback_needs_flush(AMDGPUInfoPtr info, struct amdgpu_client_priv *client_priv)
|
||||
{
|
||||
return (int)(info->callback_needs_flush - info->gpu_flushed) > 0;
|
||||
return (int)(client_priv->needs_flush - info->gpu_flushed) > 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -177,20 +180,30 @@ amdgpu_event_callback(CallbackListPtr *list,
|
||||
{
|
||||
EventInfoRec *eventinfo = call_data;
|
||||
ScrnInfoPtr pScrn = user_data;
|
||||
ScreenPtr pScreen = pScrn->pScreen;
|
||||
struct amdgpu_client_priv *client_priv =
|
||||
dixLookupScreenPrivate(&eventinfo->client->devPrivates,
|
||||
&amdgpu_client_private_key, pScreen);
|
||||
struct amdgpu_client_priv *server_priv =
|
||||
dixLookupScreenPrivate(&serverClient->devPrivates,
|
||||
&amdgpu_client_private_key, pScreen);
|
||||
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
|
||||
int i;
|
||||
|
||||
if (callback_needs_flush(info))
|
||||
if (callback_needs_flush(info, client_priv) ||
|
||||
callback_needs_flush(info, server_priv))
|
||||
return;
|
||||
|
||||
/* Don't let gpu_flushed get too far ahead of callback_needs_flush,
|
||||
* in order to prevent false positives in callback_needs_flush()
|
||||
/* Don't let gpu_flushed get too far ahead of needs_flush, in order
|
||||
* to prevent false positives in callback_needs_flush()
|
||||
*/
|
||||
info->callback_needs_flush = info->gpu_flushed;
|
||||
client_priv->needs_flush = info->gpu_flushed;
|
||||
server_priv->needs_flush = 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++;
|
||||
server_priv->needs_flush++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -201,9 +214,14 @@ amdgpu_flush_callback(CallbackListPtr *list,
|
||||
pointer user_data, pointer call_data)
|
||||
{
|
||||
ScrnInfoPtr pScrn = user_data;
|
||||
ScreenPtr pScreen = pScrn->pScreen;
|
||||
ClientPtr client = call_data ? call_data : serverClient;
|
||||
struct amdgpu_client_priv *client_priv =
|
||||
dixLookupScreenPrivate(&client->devPrivates,
|
||||
&amdgpu_client_private_key, pScreen);
|
||||
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
|
||||
|
||||
if (pScrn->vtSema && callback_needs_flush(info))
|
||||
if (pScrn->vtSema && callback_needs_flush(info, client_priv))
|
||||
amdgpu_glamor_flush(pScrn);
|
||||
}
|
||||
|
||||
@@ -273,6 +291,13 @@ static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen)
|
||||
DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!dixRegisterScreenPrivateKey(&amdgpu_client_private_key, pScreen,
|
||||
PRIVATE_CLIENT, sizeof(struct amdgpu_client_priv))) {
|
||||
DeleteCallback(&FlushCallback, amdgpu_flush_callback, pScrn);
|
||||
DeleteCallback(&EventCallback, amdgpu_event_callback, pScrn);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
Reference in New Issue
Block a user