...
 
Commits (19)
......@@ -15,7 +15,7 @@
variables:
IMAGE_TAG: "debian-testing-20181213"
IMAGE_LOCAL: "$CI_REGISTRY_IMAGE:$IMAGE_TAG"
IMAGE_MAIN: "registry.freedesktop.org/xorg/driver/$CI_PROJECT_NAME:$IMAGE_TAG"
IMAGE_MAIN: "registry.freedesktop.org/xorg/driver/xf86-video-amdgpu:$IMAGE_TAG"
stages:
- docker-image
......
......@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-video-amdgpu],
[18.1.99],
[19.0.1],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg&component=Driver/AMDgpu],
[xf86-video-amdgpu])
......
xserver-xorg-video-amdgpu (19.0.1-1) unstable; urgency=medium
* New upstream release.
-- Timo Aaltonen <tjaalton@debian.org> Sat, 06 Apr 2019 23:02:05 +0300
xserver-xorg-video-amdgpu (19.0.0-1) unstable; urgency=medium
* New upstream release.
......
......@@ -884,12 +884,18 @@ CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"%s cannot get current time\n", __func__);
if (event_info->drm_queue_seq)
if (event_info->drm_queue_seq) {
drmmode_crtc->drmmode->event_context.
vblank_handler(pAMDGPUEnt->fd, 0, 0, 0,
(void*)event_info->drm_queue_seq);
else
drmmode_crtc->wait_flip_nesting_level++;
amdgpu_drm_queue_handle_deferred(crtc);
} else {
amdgpu_dri2_frame_event_handler(crtc, 0, 0, data);
}
return 0;
}
/*
......@@ -900,13 +906,18 @@ CARD32 amdgpu_dri2_deferred_event(OsTimerPtr timer, CARD32 now, pointer data)
delta_seq = delta_t * drmmode_crtc->dpms_last_fps;
delta_seq /= 1000000;
frame = (CARD64) drmmode_crtc->dpms_last_seq + delta_seq;
if (event_info->drm_queue_seq)
if (event_info->drm_queue_seq) {
drmmode_crtc->drmmode->event_context.
vblank_handler(pAMDGPUEnt->fd, frame, drm_now / 1000000,
drm_now % 1000000,
(void*)event_info->drm_queue_seq);
else
drmmode_crtc->wait_flip_nesting_level++;
amdgpu_drm_queue_handle_deferred(crtc);
} else {
amdgpu_dri2_frame_event_handler(crtc, frame, drm_now, data);
}
return 0;
}
......
......@@ -30,6 +30,7 @@
#include <xorg-server.h>
struct amdgpu_dri2 {
drmVersionPtr pKernelDRMVersion;
Bool available;
Bool enabled;
char *device_name;
......
......@@ -361,6 +361,7 @@ void AMDGPUWindowExposures_oneshot(WindowPtr pWin, RegionPtr pRegion
);
/* amdgpu_present.c */
void amdgpu_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled);
Bool amdgpu_present_screen_init(ScreenPtr screen);
/* amdgpu_sync.c */
......
......@@ -66,6 +66,12 @@ static DevPrivateKeyRec amdgpu_window_private_key;
static DevScreenPrivateKeyRec amdgpu_client_private_key;
DevScreenPrivateKeyRec amdgpu_device_private_key;
static Atom amdgpu_vrr_atom;
static Bool amdgpu_property_vectors_wrapped;
static Bool restore_property_vector;
static int (*saved_change_property) (ClientPtr client);
static int (*saved_delete_property) (ClientPtr client);
static Bool amdgpu_setup_kernel_mem(ScreenPtr pScreen);
const OptionInfoRec AMDGPUOptions_KMS[] = {
......@@ -89,6 +95,134 @@ const OptionInfoRec *AMDGPUOptionsWeak(void)
return AMDGPUOptions_KMS;
}
static inline struct amdgpu_window_priv *get_window_priv(WindowPtr win) {
return dixLookupPrivate(&win->devPrivates, &amdgpu_window_private_key);
}
static void
amdgpu_vrr_property_update(WindowPtr window, Bool variable_refresh)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(window->drawable.pScreen);
AMDGPUInfoPtr info = AMDGPUPTR(scrn);
get_window_priv(window)->variable_refresh = variable_refresh;
if (info->flip_window == window &&
info->drmmode.present_flipping)
amdgpu_present_set_screen_vrr(scrn, variable_refresh);
}
/* Wrapper for xserver/dix/property.c:ProcChangeProperty */
static int
amdgpu_change_property(ClientPtr client)
{
WindowPtr window;
int ret;
REQUEST(xChangePropertyReq);
client->requestVector[X_ChangeProperty] = saved_change_property;
ret = saved_change_property(client);
if (restore_property_vector)
return ret;
client->requestVector[X_ChangeProperty] = amdgpu_change_property;
if (ret != Success)
return ret;
ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess);
if (ret != Success)
return ret;
if (stuff->property == amdgpu_vrr_atom &&
xf86ScreenToScrn(window->drawable.pScreen)->PreInit ==
AMDGPUPreInit_KMS && stuff->format == 32 && stuff->nUnits == 1) {
uint32_t *value = (uint32_t*)(stuff + 1);
amdgpu_vrr_property_update(window, *value != 0);
}
return ret;
}
/* Wrapper for xserver/dix/property.c:ProcDeleteProperty */
static int
amdgpu_delete_property(ClientPtr client)
{
WindowPtr window;
int ret;
REQUEST(xDeletePropertyReq);
client->requestVector[X_DeleteProperty] = saved_delete_property;
ret = saved_delete_property(client);
if (restore_property_vector)
return ret;
client->requestVector[X_DeleteProperty] = amdgpu_delete_property;
if (ret != Success)
return ret;
ret = dixLookupWindow(&window, stuff->window, client, DixSetPropAccess);
if (ret != Success)
return ret;
if (stuff->property == amdgpu_vrr_atom &&
xf86ScreenToScrn(window->drawable.pScreen)->PreInit ==
AMDGPUPreInit_KMS)
amdgpu_vrr_property_update(window, FALSE);
return ret;
}
static void
amdgpu_unwrap_property_requests(ScrnInfoPtr scrn)
{
int i;
if (!amdgpu_property_vectors_wrapped)
return;
if (ProcVector[X_ChangeProperty] == amdgpu_change_property)
ProcVector[X_ChangeProperty] = saved_change_property;
else
restore_property_vector = TRUE;
if (ProcVector[X_DeleteProperty] == amdgpu_delete_property)
ProcVector[X_DeleteProperty] = saved_delete_property;
else
restore_property_vector = TRUE;
for (i = 0; i < currentMaxClients; i++) {
if (clients[i]->requestVector[X_ChangeProperty] ==
amdgpu_change_property) {
clients[i]->requestVector[X_ChangeProperty] =
saved_change_property;
} else {
restore_property_vector = TRUE;
}
if (clients[i]->requestVector[X_DeleteProperty] ==
amdgpu_delete_property) {
clients[i]->requestVector[X_DeleteProperty] =
saved_delete_property;
} else {
restore_property_vector = TRUE;
}
}
if (restore_property_vector) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Couldn't unwrap some window property request vectors\n");
}
amdgpu_property_vectors_wrapped = FALSE;
}
extern _X_EXPORT int gAMDGPUEntityIndex;
static int getAMDGPUEntityIndex(void)
......@@ -146,6 +280,7 @@ static void AMDGPUFreeRec(ScrnInfoPtr pScrn)
pAMDGPUEnt = pPriv->ptr;
pAMDGPUEnt->fd_ref--;
if (!pAMDGPUEnt->fd_ref) {
amdgpu_unwrap_property_requests(pScrn);
amdgpu_device_deinitialize(pAMDGPUEnt->pDev);
amdgpu_kernel_close_fd(pAMDGPUEnt);
free(pPriv->ptr);
......@@ -156,52 +291,6 @@ static void AMDGPUFreeRec(ScrnInfoPtr pScrn)
free(pEnt);
}
static inline struct amdgpu_window_priv *get_window_priv(WindowPtr win) {
return dixLookupPrivate(&win->devPrivates, &amdgpu_window_private_key);
}
static void
amdgpu_property_notify(ClientPtr client,
XID id,
int state,
ATOM property_name)
{
WindowPtr win;
PropertyPtr prop;
struct amdgpu_window_priv *priv;
const char* str;
int res;
res = dixLookupWindow(&win, id, client, DixReadAccess);
if (res != Success)
return;
str = NameForAtom(property_name);
if (str == NULL)
return;
if (strcmp(str, "_VARIABLE_REFRESH") != 0)
return;
priv = get_window_priv(win);
if (!priv)
return;
priv->variable_refresh = 0;
res = dixLookupProperty(&prop,
win,
property_name,
client,
DixReadAccess);
if (res == Success && prop->format == 32 && prop->size == 1) {
uint32_t value = *(uint32_t*)prop->data;
priv->variable_refresh = (value != 0);
}
}
Bool amdgpu_window_has_variable_refresh(WindowPtr win) {
struct amdgpu_window_priv *priv = get_window_priv(win);
......@@ -249,17 +338,6 @@ amdgpu_event_callback(CallbackListPtr *list,
AMDGPUInfoPtr info = AMDGPUPTR(pScrn);
int i;
if (info->vrr_support) {
for (i = 0; i < eventinfo->count; i++) {
xEventPtr ev = &eventinfo->events[i];
if (ev->u.u.type == PropertyNotify)
amdgpu_property_notify(eventinfo->client,
ev->u.property.window,
ev->u.property.state,
ev->u.property.atom);
}
}
if (callback_needs_flush(info, client_priv) ||
callback_needs_flush(info, server_priv))
return;
......@@ -365,7 +443,8 @@ static Bool AMDGPUCreateScreenResources_KMS(ScreenPtr pScreen)
}
}
if (!dixRegisterPrivateKey(&amdgpu_window_private_key,
if (info->vrr_support &&
!dixRegisterPrivateKey(&amdgpu_window_private_key,
PRIVATE_WINDOW,
sizeof(struct amdgpu_window_priv)))
return FALSE;
......@@ -1516,6 +1595,12 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
info->dri2.available = FALSE;
info->dri2.enabled = FALSE;
info->dri2.pKernelDRMVersion = drmGetVersion(pAMDGPUEnt->fd);
if (info->dri2.pKernelDRMVersion == NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"AMDGPUDRIGetVersion failed to get the DRM version\n");
return FALSE;
}
/* Get ScreenInit function */
if (!xf86LoadSubModule(pScrn, "fb"))
......@@ -1550,11 +1635,13 @@ Bool AMDGPUPreInit_KMS(ScrnInfoPtr pScrn, int flags)
if (info->shadow_primary)
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowPrimary enabled\n");
from = xf86GetOptValBool(info->Options, OPTION_VARIABLE_REFRESH,
&info->vrr_support) ? X_CONFIG : X_DEFAULT;
if (!pScrn->is_gpu) {
from = xf86GetOptValBool(info->Options, OPTION_VARIABLE_REFRESH,
&info->vrr_support) ? X_CONFIG : X_DEFAULT;
xf86DrvMsg(pScrn->scrnIndex, from, "VariableRefresh: %sabled\n",
info->vrr_support ? "en" : "dis");
xf86DrvMsg(pScrn->scrnIndex, from, "VariableRefresh: %sabled\n",
info->vrr_support ? "en" : "dis");
}
}
if (!pScrn->is_gpu) {
......@@ -2092,6 +2179,19 @@ Bool AMDGPUScreenInit_KMS(ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
if (info->vrr_support) {
if (!amdgpu_property_vectors_wrapped) {
saved_change_property = ProcVector[X_ChangeProperty];
ProcVector[X_ChangeProperty] = amdgpu_change_property;
saved_delete_property = ProcVector[X_DeleteProperty];
ProcVector[X_DeleteProperty] = amdgpu_delete_property;
amdgpu_property_vectors_wrapped = TRUE;
}
amdgpu_vrr_atom = MakeAtom("_VARIABLE_REFRESH",
strlen("_VARIABLE_REFRESH"), TRUE);
}
drmmode_init(pScrn, &info->drmmode);
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, AMDGPU_LOGLEVEL_DEBUG,
......
......@@ -90,7 +90,7 @@ amdgpu_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc)
/*
* Changes the variable refresh state for every CRTC on the screen.
*/
static void
void
amdgpu_present_set_screen_vrr(ScrnInfoPtr scrn, Bool vrr_enabled)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
......@@ -255,6 +255,7 @@ amdgpu_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
xf86CrtcPtr xf86_crtc = crtc->devPrivate;
ScreenPtr screen = window->drawable.pScreen;
ScrnInfoPtr scrn = xf86_crtc->scrn;
PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
AMDGPUInfoPtr info = AMDGPUPTR(scrn);
int num_crtcs_on;
......@@ -272,12 +273,23 @@ amdgpu_present_check_flip(RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap,
if (info->drmmode.dri2_flipping)
return FALSE;
/* The kernel driver doesn't handle flipping between BOs with different
* tiling parameters correctly yet
*/
if (amdgpu_pixmap_get_tiling_info(pixmap) !=
amdgpu_pixmap_get_tiling_info(screen->GetScreenPixmap(screen)))
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(1, 20, 99, 1, 0)
if (pixmap->devKind != screen_pixmap->devKind)
return FALSE;
#endif
/* Only DC supports advanced color management features, so we can use
* drmmode_cm_enabled as a proxy for "Is DC enabled?"
*/
if (info->dri2.pKernelDRMVersion->version_minor < 31 ||
!drmmode_cm_enabled(&info->drmmode)) {
/* The kernel driver doesn't handle flipping between BOs with
* different tiling parameters correctly
*/
if (amdgpu_pixmap_get_tiling_info(pixmap) !=
amdgpu_pixmap_get_tiling_info(screen_pixmap))
return FALSE;
}
for (i = 0, num_crtcs_on = 0; i < config->num_crtc; i++) {
if (drmmode_crtc_can_flip(config->crtc[i]))
......
......@@ -826,14 +826,6 @@ static enum drmmode_cm_prop get_cm_enum_from_str(const char *prop_name)
return CM_INVALID_PROP;
}
/**
* Return TRUE if kernel supports non-legacy color management.
*/
static Bool drmmode_cm_enabled(drmmode_ptr drmmode)
{
return drmmode->cm_prop_ids[CM_GAMMA_LUT_SIZE] != 0;
}
/**
* If legacy LUT is a, and non-legacy LUT is b, then the result of b(a(x)) is
* returned in out_lut. out_lut's length is expected to be the same as the
......@@ -2150,6 +2142,51 @@ drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
return MODE_OK;
}
static void
drmmode_output_attach_tile(xf86OutputPtr output)
{
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1, 17, 99, 901, 0)
drmmode_output_private_ptr drmmode_output = output->driver_private;
drmModeConnectorPtr koutput = drmmode_output->mode_output;
AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(output->scrn);
struct xf86CrtcTileInfo tile_info, *set = NULL;
int i;
if (!koutput) {
xf86OutputSetTile(output, NULL);
return;
}
/* look for a TILE property */
for (i = 0; i < koutput->count_props; i++) {
drmModePropertyPtr props;
props = drmModeGetProperty(pAMDGPUEnt->fd, koutput->props[i]);
if (!props)
continue;
if (!(props->flags & DRM_MODE_PROP_BLOB)) {
drmModeFreeProperty(props);
continue;
}
if (!strcmp(props->name, "TILE")) {
drmModeFreePropertyBlob(drmmode_output->tile_blob);
drmmode_output->tile_blob =
drmModeGetPropertyBlob(pAMDGPUEnt->fd,
koutput->prop_values[i]);
}
drmModeFreeProperty(props);
}
if (drmmode_output->tile_blob) {
if (xf86OutputParseKMSTile(drmmode_output->tile_blob->data,
drmmode_output->tile_blob->length,
&tile_info) == TRUE)
set = &tile_info;
}
xf86OutputSetTile(output, set);
#endif
}
static int
koutput_get_prop_idx(int fd, drmModeConnectorPtr koutput,
int type, const char *name)
......@@ -2221,6 +2258,8 @@ static DisplayModePtr drmmode_output_get_modes(xf86OutputPtr output)
}
xf86OutputSetEDID(output, mon);
drmmode_output_attach_tile(output);
/* modes should already be available */
for (i = 0; i < koutput->count_modes; i++) {
Mode = xnfalloc(sizeof(DisplayModeRec));
......@@ -2238,8 +2277,11 @@ static void drmmode_output_destroy(xf86OutputPtr output)
drmmode_output_private_ptr drmmode_output = output->driver_private;
int i;
if (drmmode_output->edid_blob)
drmModeFreePropertyBlob(drmmode_output->edid_blob);
drmModeFreePropertyBlob(drmmode_output->edid_blob);
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1, 17, 99, 901, 0)
drmModeFreePropertyBlob(drmmode_output->tile_blob);
#endif
for (i = 0; i < drmmode_output->num_props; i++) {
drmModeFreeProperty(drmmode_output->props[i].mode_prop);
free(drmmode_output->props[i].atoms);
......
......@@ -163,6 +163,9 @@ typedef struct {
drmModeConnectorPtr mode_output;
drmModeEncoderPtr *mode_encoders;
drmModePropertyBlobPtr edid_blob;
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1, 17, 99, 901, 0)
drmModePropertyBlobPtr tile_blob;
#endif
int dpms_enum_id;
int num_props;
drmmode_prop_ptr props;
......@@ -182,6 +185,15 @@ enum drmmode_flip_sync {
};
/**
* Return TRUE if kernel supports non-legacy color management.
*/
static inline Bool
drmmode_cm_enabled(drmmode_ptr drmmode)
{
return drmmode->cm_prop_ids[CM_GAMMA_LUT_SIZE] != 0;
}
/* Can the page flip ioctl be used for this CRTC? */
static inline Bool
drmmode_crtc_can_flip(xf86CrtcPtr crtc)
......