Try to minimize the used hw cursor size in order to
minimize power consumption. There is no kernel query
for the minimum so we'll just probe around with
setcursor2 (using an invisible cursor image so
there will be no visual artifacts).
To avoid having to deal with absolutely every size stick
to power-of-two numbers. And with a bit of extra effort
we can determine whether non-square dimesions will also
work, which they do to some degree on current Intel GPUs.
On my Alderlake laptop I'm seeing a massive (up to .5W)
difference in power consumption between 64x64 vs. 256x256
cursors. While some of that is undoubtedly something that
needs to be fixed in i915's display data buffer allocation
code, it still makes sense to use as small as possible
cursor to minimize the wastege.
In case the crtc is rotated just punt to the max cursor size
for now since midlayer has already done the coordinate
transformations based on that. To make smaller cursors work
with rotation we'd either need to make the midlayer(s) aware
of the final cursor size, or just handle the whole roation
business in modesetting. I suspect the latter option would
be easier.
v2: Only allow square cursors in most cases for now as eg.
on modern Intel hardware non-square only works with
wide+short but not with narrow+tall cursors. Non-square
size may still be used when maximum limits aren't
square and the squared+POT'd dimensions would exceed
one of the max limits.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Make sure we're not scanning out any fbs with fancy modifiers when
we try to light up new displays. This is already the case in cases
where the screen gets resized, but in cases where that doesn't happen
it might be possible for the modeset(s) to fail due to watermark/etc.
constraints imposed by the fancy modifiers. We can avoid that by
making sure everything gets unflipped before the modeset.
v2: make poll timeout infinite
s/in_modeset/pending_modeset/
deal with tearfree fallout (goto no_flip)
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
When using TearFree, DRI clients have no way of accurately knowing when
their copied pixmaps appear on the display without utilizing the kernel
driver's notification indicating that the TearFree flip containing their
pixmap is complete. This is because the target CRTC's MSC can change while
the predicted completion MSC is calculated and even while the page flip
IOCTL is sent to the kernel due to scheduling delays and/or unfortunate
timing. Even worse, a page flip isn't actually guaranteed to be finished
after one vblank; it may be several MSCs until a flip actually finishes
depending on delays and load in hardware.
As a result, DRI clients may be off by one or more MSCs when they naively
expect their pixmaps to be visible at MSC+1 with TearFree enabled. This,
for example, makes it impossible for DRI clients to achieve precise A/V
synchronization when TearFree is enabled.
This change therefore adds a way for DRI clients to receive a notification
straight from the TearFree flip-done handler to know exactly when their
pixmaps appear on the display. This is done by checking for a NULL pixmap
pointer to modesetting's DRI flip routine, which indicates that the DRI
client has copied its pixmap and wants TearFree to send a notification when
the copied pixmap appears on the display as part of a TearFree flip. The
existing PageFlip scaffolding is reused to achieve this with minimal churn.
The Present extension will be updated in an upcoming change to utilize this
new mechanism for DRI clients' presentations.
Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
Acked-by: Martin Roukala <martin.roukala@mupuf.org>
This adds support for TearFree page flips to eliminate tearing without the
use of a compositor. It allocates two shadow buffers for each CRTC, a back
buffer and a front buffer, and uses damage tracking to minimize excessive
copying between buffers and skip unnecessary flips when the screen's
contents remain unchanged. It works on transformed screens too, such as
rotated and scaled CRTCs.
When PageFlip is enabled, TearFree won't force fullscreen DRI clients to
synchronize their page flips to the vblank interval.
TearFree is disabled by default.
Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
The DRM event queue in the kernel is quite small and can be easily
exhausted by DRI clients. When the event queue is full, that means nothing
can be queued onto it anymore, which can lead to incorrect presentation
times for DRI clients and failure when attempting to queue a page flip.
To make matters worse, once an event is placed onto the kernel's event
queue, there's no straightforward way to prematurely remove it from the
kernel's event queue in userspace, which means that aborting a sequence
number doesn't free up space in the event queue.
Since vblank events from DRI clients are the largest consumers of the
event queue, and since it's often easy to know the desired target MSC of
their vblank events without querying the kernel for a CRTC's current MSC,
we can coalesce vblank events occurring at the same MSC such that only one
of them is placed onto the kernel's event queue, instead of allowing
duplicate vblank events to pollute the event queue.
This is achieved by tracking the next kernel-queued event's MSC on a
per-CRTC basis and then running all of that CRTC's vblank event handlers
which have reached their target MSC when the queued MSC is signaled.
Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
do_queue_flip_on_crtc() is about to be used to flip buffers other than the
primary scanout (`ms->drmmode.fb_id`), so make it generic to accept any
frame buffer ID, as well as x and y coordinates in the frame buffer, to
flip on a given CRTC. Move the retry logic from queue_flip_on_crtc() into
it as well, so that it's robust for all callers.
Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
Rotation is broken for all drm drivers not providing hardware rotation
support. Drivers that give direct access to vram and not needing dirty
updates still work but only by accident. The problem is caused by
modesetting not sending the correct fb_id to drmModeDirtyFB() and
passing the damage rects in the rotated state and not as the crtc
expects them. This patch takes care of both problems.
Signed-off-by: Patrik Jakobsson <pjakobsson@suse.de>
Whenever an unredirected fullscreen window uses pageflipping for a
DRI3/Present PresentPixmap() operation and the X-Screen has more than
one active output, multiple crtc's need to execute pageflips. Only
after the last flip has completed can the PresentPixmap operation
as a whole complete.
If a sync_flip is requested for the present, then the current
implementation will synchronize each pageflip to the vblank of
its associated crtc. This provides tear-free image presentation
across all outputs, but introduces a different artifact, if not
all outputs run at the same refresh rate with perfect synchrony:
The slowest output throttles the presentation rate, and present
completion is delayed to flip completion of the "latest" output
to complete. This means degraded performance, e.g., a dual-display
setup with a 144 Hz monitor and a 60 Hz monitor will always be
throttled to at most 60 fps. It also means non-constant present
rate if refresh cycles drift against each other, creating complex
"beat patterns", tremors, stutters and periodic slowdowns - quite
irritating!
Such a scenario will be especially annoying if one uses multiple
outputs in "mirror mode" aka "clone mode". One output will usually
be the "production output" with the highest quality and fastest
display attached, whereas a secondary mirror output just has a
cheaper display for monitoring attached. Users care about perfect
and perfectly timed tear-free presentation on the "production output",
but cares less about quality on the secondary "mirror output". They
are willing to trade quality on secondary outputs away in exchange
for better presentation timing on the "production output".
One example use case for such production + monitoring displays are
neuroscience / medical science applications where one high quality
display device is used to present visual animations to test subjects
or patients in a fMRI scanner room (production display), whereas
an operator monitors the same visual animations from a control room
on a lower quality display. Presentation timing needs to be perfect,
and animations high-speed and tear-free for the production display,
whereas quality and timing don't matter for the monitoring display.
This commit gives users the option to choose such a trade-off as
opt-in:
It adds a new boolean option "AsyncFlipSecondaries" to the device section
of xorg.conf. If this option is specified as true, then DRI3 pageflip
behaviour changes as follows:
1. The "reference crtc" for a windows PresentPixmap operation does a
vblank synced flip, or a DRM_MODE_PAGE_FLIP_ASYNC non-synchronized
flip, as requested by the caller, just as in the past. Typically
flips will be requested to be vblank synchronized for tear-free
presentation. The "reference crtc" is the one chosen by the caller
to drive presentation timing (as specified by PresentPixmap()'s
"target_msc", "divisor", "remainder" parameters and implemented by
vblank events) and to deliver Present completion timestamps (msc
and ust) extracted from its pageflip completion event.
2. All other crtc's, which also page-flip in a multi-display configuration,
will try to flip with DRM_MODE_PAGE_FLIP_ASYNC, ie. immediately and
not synchronized to vblank. This allows the PresentPixmap operation
to complete with little delay compared to a single-display present,
especially if the different crtc's run at different video refresh
rates or their refresh cycles are not perfectly synchronized, but
drift against each other. The downside is potential tearing artifacts
on all outputs apart from the one of the "reference crtc".
Successfully tested on a AMD gpu with single-display, dual-display and
triple-display setups, and with single-X-Screen as well as dual-X-Screen
"ZaphodHeads" configurations.
Please consider merging this commit for the upcoming server 1.21 branch.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
When the "CTM" (color transform matrix) modesetting property is available,
create a corresponding RandR property.
To match the format of the property available in the amdgpu driver, expose it as
an array of 18 32-bit XA_INTEGERs representing a 3x3 matrix in row-major order,
where each entry is a S31.32 sign-magnitude fixed-point number with the
fractional part listed first.
Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
Acked-by: Michel Dänzer <mdaenzer@redhat.com>
Reviewed-by: James Jones <jajones@nvidia.com>
If the kernel exposes GAMMA_LUT and GAMMA_LUT_SIZE properties and the size is
not what the server has pre-configured for the crtc, free the old gamma ramp
memory allocated by the server and replace it with new allocations of the
appropriate size.
In addition, when GAMMA_LUT is available, use drmModeCreatePropertyBlob() and
drmModeObjectSetProperty() to set the gamma ramp rather than using the legacy
drmModeCrtcSetGamma() function.
Add a new option "UseGammaLUT" to allow disabling this new behavior and falling
back to drmModeCrtcSetGamma() unconditionally.
Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
There was a time when setting a mode on a CRTC would not depend on the
associated connector's state. If a mode had been set successfully once,
it would mean it would work later on.
This changed with the introduction of new connectors type that now
require a link training sequence (DP, HDMI 2.0), and that means that
some events may have happened while the X server was not master that
would then prevent the mode from successfully be restored to its
previous state.
This patch relaxes the requirement that all modes should be restored on
EnterVT, or the entire X-Server would go down by allowing modesets to
fail (with some warnings). If a modeset fails, the CRTC will be
disabled, and a RandR event will be sent for the desktop environment to
fix the situation as well as possible.
Additional patches might be needed to make sure that the user would
never be left with all screens black in some scenarios.
v2 (Martin Peres):
- whitespace fixes
- remove the uevent handling (it is done in a previous patch)
- improve the commit message
- reduce the size of the patch by not changing lines needlessly
- return FALSE if one modeset fails in ignore mode
- add comments/todos to explain why we do things
- disable the CRTCs that failed the modeset
Signed-off-by: Kishore Kadiyala <kishore.kadiyala@intel.com>
Signed-off-by: Martin Peres <martin.peres@linux.intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Tested-by: Kishore Kadiyala <kishore.kadiyala@intel.com>
Closes: #1010
Normally, we would receive a uevent coming from Linux's DRM subsystem,
which would trigger the check for disappearing/appearing resources.
However, this event is not received when X is not master (another VT
is selected), and so the userspace / desktop environment would not be
notified about the changes that happened while X wasn't master.
To fix the issue, this patch forces a refresh on EnterVT by splitting
the kms-checking code from the uevent handling into its own (exported)
function called drmmode_update_kms_state. This function is then called
from both the uevent-handling function, and on EnterVT right before
restoring the modes.
Signed-off-by: Martin Peres <martin.peres@linux.intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Kishore Kadiyala <kishore.kadiyala@intel.com>
Tested-by: Kishore Kadiyala <kishore.kadiyala@intel.com>
These changes have been ported from AMD GPU DDX driver.
This patch adds support for setting the CRTC variable refresh property
for suitable windows flipping via the Present extension.
In order for a window to be suitable for variable refresh it must have
the _VARIABLE_REFRESH property set by the MESA and inform Modesetting
DDX driver with window property updates.
Then the window must pass the checks required to be suitable for
Present extension flips - it must cover the entire X screen and no
other window may already be flipping. And also DRM connector should
be VRR capable.
With these conditions met every CRTC for the X screen will have their
variable refresh property set to true.
Kernel Changes to support this feature in I915 driver is under development.
Tested with DOTA2, Xonotic and custom GLX apps.
Signed-off-by: Uday Kiran Pichika <pichika.uday.kiran@intel.com>
Only log 1 error for consecutive flip failures, instead of filling the
log and the disk with errors for each attempted flip.
Despite our best efforts we may end up with a BO which gets refused
when we try to import it as a framebuffer, see e.g. :
https://bugs.freedesktop.org/show_bug.cgi?id=111306
This should not happen, but as the above bugs shows sometimes it does
and chances are it will happen again.
Note ideally we should check if the import is possible at
ms_present_check_flip time, like the amdgpu code is doing since:
https://gitlab.freedesktop.org/xorg/driver/xf86-video-amdgpu/merge_requests/35
but that requires a chunk of refactoring work on the modesetting driver,
so for now this will have to do.
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
The miPointerSpriteFunc swcursor code expects there to only be a single
framebuffer and when the cursor moves it will undo the damage of the
previous draw, potentially overwriting what ever is there in a new
framebuffer installed after a flip.
This leads to all kind of artifacts, so we need to disable pageflipping
when a swcursor is used.
The code for this has shamelessly been copied from the xf86-video-amdgpu
code.
Fixes: https://gitlab.freedesktop.org/xorg/xserver/issues/828
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
When the pixmapPrivateKeyRec was moved from a global to being embedded
inside the drmmode_rec these 2 where missed, clean them up.
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Instead of having every video driver loop over any pending leases to
free them during CloseScreen, do this up in the DIX layer by
terminating leases when a leased CRTC or Output is destroyed and
(just to make sure), also terminating leases in RRCloseScreen. The
latter should "never" get invoked as any lease should be associated
with a resource which was destroyed.
This is required as by the time the driver's CloseScreen function is
invoked, we've already freed all of the DIX randr structures and no
longer have any way to reference the leases
Signed-off-by: Keith Packard <keithp@keithp.com>
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=106960
Cc: Thomas Hellstrom <thellstrom@vmware.com>
The function is ported from intel-ddx uxa backend around 2013, where its
stated purpose was to apply a vblank_offset to msc values to correct for
problems with those kernel provided msc values. Some (somewhat magic and
puzzling to myself) heuristic tried to guess if provided values were
unreasonable and tried to adapt the corrective vblank_offset to account
for that.
Except: It wasn't applied to kernel provided msc values, but the values
delivered by clients via DRI2 or Present, so valid client targetmsc
values, e.g., requesting a vblank event > 1000 vblanks in the future,
triggered the offset correction in arbitrarily wrong ways, leading to
wrong msc values being returned and thereby vblank events queued to the
kernel for the wrong time. This causes glXSwapBuffersMscOML and
glXWaitForMscOML to swap / return immediately whenever a swap/wait in >
1000 vblanks is requested.
The original code was also written to only deal with 32 bit mscs, but
server 1.20 modesetting ddx can now use new Linux 4.15+ kernel vblank
api to process true 64 bit msc's, which may confuse the heuristic even
more due to 32 bit integer truncation/wrapping.
This code caused various problems in the intel-ddx in the past since
year 2013, and was removed there in 2015 by Chris Wilson in commit
42ebe2ef9646be5c4586868cf332b4cd79bb4618:
" uxa: Remove the filtering of bogus Present MSC values
If the intention was to filter the return values from the kernel, the
filtering would have been applied to the kernel values and not to the
incoming values from Present. This filtering introduces crazy integer
promotion and truncation bugs all because Present feeds garbage into its
vblank requests.
"
Indeed, i found a Mesa bug yesterday which can cause Mesa's
PresentPixmap request to spuriously feed garbage targetMSC's into the
driver under some conditions. However, while other video drivers seem to
cope relatively well with that, modesetting ddx causes KDE-5's
plasmashell to lock up badly quite frequently, and my suspicion is that
the code removed in this commit is one major source of the extra
fragility.
Also my own tests fail for any swap scheduled more than 1000 vblanks
into the future, which is not uncommon for some scientific applications.
Iow. modesetting's swap scheduling seems to be more robust without this
function afaics.
Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Keith Packard <keithp@keithp.com>
Tested-by: Mike Lothian <mike@fireburn.co.uk>
We need to make sure that the atomic commit are consistent
or else the kernel will reject it. For example, when moving
a CRTC from one output to another one, the first output CRTC_ID
property needs to be reset. Also if the second output was using
another CRTC beforehands, it needs to be disabled to avoid an
inconsistent state.
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Tested-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
CRTCs and outputs needs to be enabled/disabled when the current
DPMS mode is changed. We also try to do it in an atomic commit
when possible.
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Tested-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Keep track of whether or not we fed modifiers into GBM when we allocated
a BO. We'll use this later inside Glamor, to reallocate buffer storage
if we allocate buffer storage using modifiers, and a non-modifier-aware
client requests an export of that pixmap.
This makes it possible to run a compositing manager on an old GLX/EGL
stack on top of an X server which allocates internal buffer storage
using exotic modifiers from modifier-aware GBM/EGL/KMS.
Signed-off-by: Daniel Stone <daniels@collabora.com>
Reported-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
All the macros are available in the libdrm that we depend on.
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Implement function added in DRI3 v1.1.
A newest version of libepoxy (>= 1.4.4) is required as earlier
versions use a problematic version of Khronos
EXT_image_dma_buf_import_modifiers spec.
v4: Only send scanout-supported modifiers if flipping is possible
v5: Fix memory corruption in XWayland (uninitialized pointer)
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Acked-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Add support for 'check_flip2' so that the present core can know
why it is impossible to flip in that scenario. The core can then
let know the client that the buffer format/modifier is suboptimal.
v2: No longer need to implement 'check_flip'
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Acked-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Retrieve IN_FORMATS property from the plane. It gives the
allowed formats and modifiers for BO allocation.
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Acked-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
To make sure we also use the same primary plane and to avoid
mixing uses of two APIs, it is better to always use the atomic
modesetting API when possible.
v2: Don't use mode_output->connector_id
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Acked-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
This allows the uses of CCS compressed or tiled pixmaps as BOs when
page-flipping.
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Acked-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
In order to flip between compressed and uncompressed buffers -
something drmModePageFlip explicitly bans us from doing - we need
to port use the atomic modesetting API. It's only 'fake' atomic
though given we still commit for each CRTC separately and
CRTC and connector properties are not set with the atomic API.
The helper functions to retrieve DRM properties have been borrowed
from Weston.
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Acked-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
This adds support for RandR CRTC/Output leases through the modesetting
driver, creating a lease using new kernel infrastructure and returning
that to a client through an fd which will have access to only those
resources.
v2: Restore CRTC mode when leases terminate
When a lease terminates for a crtc we have saved data for, go
ahead and restore the saved mode.
v3: Report RR_Rotate_0 rotations for leased crtcs.
Ignore leased CRTCs when selecting screen size.
Stop leasing encoders, the kernel doesn't do that anymore.
Turn off crtc->enabled while leased so that modesetting
ignores them.
Check lease status before calling any driver mode functions
When starting a lease, mark leased CRTCs as disabled and hide
their cursors. Also, check to see if there are other
non-leased CRTCs which are driving leased Outputs and mark
them as disabled as well. Sometimes an application will lease
an idle crtc instead of the one already associated with the
leased output.
When terminating a lease, reset any CRTCs which are driving
outputs that are no longer leased so that they start working
again.
This required splitting the DIX level lease termination code
into two pieces, one to remove the lease from the system
(RRLeaseTerminated) and a new function that frees the lease
data structure (RRLeaseFree).
v4: Report RR_Rotate_0 rotation for leased crtcs.
v5: Terminate all leases on server reset.
Leases hang around after the associated client exits so that
the client doesn't need to occupy an X server client slot and
consume a file descriptor once it has gotten the output
resources necessary.
Any leases still hanging around when the X server resets or
shuts down need to be cleaned up by calling the kernel to
terminate the lease and freeing any DIX structures.
Note that we cannot simply use the existing
drmmode_terminate_lease function on each lease as that wants
to also reset the video mode, and during server shut down that
modesetting: Validate leases on VT enter
The kernel doesn't allow any master ioctls to run when another
VT is active, including simple things like listing the active
leases. To deal with that, we check the list of leases
whenever the X server VT is activated.
xfree86: hide disabled cursors when resetting after lease termination
The lessee may well have played with cursors and left one
active on our screen. Just tell the kernel to turn it off.
v6: Add meson build infrastructure
[Also bumped libdrm requirement - ajax]
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Roundhouse kick replacing the various (sizeof(foo)/sizeof(foo[0])) with
the ARRAY_SIZE macro from dix.h when possible. A semantic patch for
coccinelle has been used first. Additionally, a few macros have been
inlined as they had only one or two users.
Signed-off-by: Daniel Martin <consume.noise@gmail.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
This allows making the master screen's pixmap_dirty_list entries
explicitly reflect that we're now tracking the root window instead of
the screen pixmap, in order to allow Present page flipping on master
outputs while there are active slave outputs.
Define HAS_DIRTYTRACKING_DRAWABLE_SRC for drivers to check, but leave
HAS_DIRTYTRACKING_ROTATION defined as well to make things slightly
easier for drivers.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Currently if modesetting ever fails to set a hardware cursor it will switch
to using a software cursor and never go back. Change this to only
permanently switch to a software cursor if -ENXIO is returned (which means
hardware cursors not supported), and to otherwise still try a hardware
cursor first every time a new one is set. This is needed because hardware
may be able to handle some cursors in hardware and others not, or virtual
hardware may be able to handle hardware cursors at some times and not
others.
Changes since v1, v2 and v3:
* take into account the switch to load_cursor_argb_check
* keep the permanent software cursor fall-back if -ENXIO is returned
* move parts of v3 into separate patches
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Michael Thayer <michael.thayer@oracle.com>
Based on v4 by Alexandre Courbot <acourbot@nvidia.com>
There is currently no reliable way to report failure to set a HW
cursor. Still such failures can happen if e.g. the MODE_CURSOR DRM
ioctl fails (which currently happens at least with modesetting on Tegra
for format incompatibility reasons).
As failures are currently handled by setting the HW cursor size to
(0,0), the fallback to SW cursor will not happen until the next time the
cursor changes and xf86CursorSetCursor() is called again. In the
meantime, the cursor will be invisible to the user.
This patch addresses that by adding _xf86CrtcFuncs::set_cursor_check and
_xf86CursorInfoRec::ShowCursorCheck hook variants that return booleans.
This allows to propagate errors up to xf86CursorSetCursor(), which can
then fall back to using the SW cursor immediately.
v5:
- Removed parts of patch already committed as part of 14c21ea1.
- Adjusted code slightly to match surrounding code.
- Effectively reverted af916477 which is made unnecessary by this patch.
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Michael Thayer <michael.thayer@oracle.com>
The modesetting driver may be driving 2 screens (slave and master
gpu), which may have different behavior wrt hardware cursor support.
So stop using static variables and instead store the hw-cursor support
related data in a per screen struct. While at it actually make it per
crtc data as in theory different crtc's could have different hw-cursor
support.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Keith Packard <keithp@keithp.com>
Embarassingly, it looks like I introduced this dead function in
commit 13c7d53df8 a year ago.
Nothing ever used it, not even then.
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Server GPUs often have a VNC feature attached to allow remote console.
The controller implementing this feature is usually not very powerful,
and we can easily swamp it with work. This is made somewhat worse by
damage over-reporting the size of the dirty region, and a whole lot
worse by applications (or shells) that update the screen with identical
pixel content as was already there.
Fix this by double-buffering the shadow fb, using memcmp to identify
dirty tiles on each update pass. Since both shadows are in host memory
the memcmp is cheap, and worth it given the win in network bandwidth.
The tile size is somewhat arbitrarily chosen to be one cacheline wide at
32bpp on Intel Core.
By default we enable this behaviour for (a subset of) known server GPUs;
the heuristic could use work.
Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
24bpp front buffers tend to be the least well tested path for client
rendering. On the qemu cirrus emulation, and on some Matrox G200 server
chips, the hardware can't do 32bpp at all. It's better to just allocate
a 32bpp shadow and downconvert in the upload hook than expose a funky
pixmap format to clients.
[ajax: Ported from RHEL and separate modesetting driver, lifted kbpp
into the drmmode struct, cleaned up commit message, fixed 16bpp]
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Dave Airlied <airlied@redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
[hdegoede@redhat.com: rebase, also use kbpp for rotate shadow fb]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Implements (Start/Stop)FlippingPixmapTracking, PresentSharedPixmap, and
RequestSharedPixmapNotifyDamage, the source functions for PRIME
synchronization and double buffering. Allows modesetting driver to be used
as a source with PRIME synchronization.
v1: N/A
v2: N/A
v3: N/A
v4: Initial commit
v5: Move disabling of reverse PRIME on sink to sink commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
Implements (Enable/Disable)SharedPixmapFlipping and
SharedPixmapNotifyDamage, the sink functions for PRIME synchronization and
double buffering. Allows modesetting driver to be used as a sink with PRIME
synchronization.
Changes dispatch_slave_dirty to flush damage from both scanout pixmaps.
Changes drmmode_set_scanout_pixmap*() functions to
drmmode_set_target_scanout_pixmap*() that take an additional parameter
PixmapPtr *target. Then, treat *target as it did prime_pixmap. This allows
me to use it to explicitly set both prime_pixmap and prime_pixmap_back
individually. drmmode_set_scanout_pixmap() without the extra parameter
remains to cover the single-buffered case, but only works if we aren't
already double buffered.
driver.c:
Add plumbing for rr(Enable/Disable)SharedPixmapFlipping and
SharedPixmapNotifyDamage.
Change dispatch_dirty_crtc to dispatch_dirty_pixmap, which functions the
same but flushes damage associated with a ppriv instead of the crtc, and
chanage dispatch_slave_dirty to use it on both scanout pixmaps if
applicable.
drmmode_display.h:
Add flip_seq field to msPixmapPrivRec to keep track of the event handler
associated with a given pixmap, if any.
Add wait_for_damage field to msPixmapPrivRec to keep track if we have
requested a damage notification from the source.
Add enable_flipping field to drmmode_crtc_private_rec to keep track if
flipping is enabled or disabled.
Add prime_pixmap_back to drmmode_crtc_private_rec to keep track of back
buffer internally.
Add declarations for drmmode_SetupPageFlipFence(),
drmmode_EnableSharedPixmapFlipping(),
drmmode_DisableSharedPixmapFlipping, drmmode_SharedPixmapFlip(), and
drmmode_SharedPixmapPresentOnVBlank().
Move slave damage from crtc to ppriv.
drmmode_display.c:
Change drmmode_set_scanout_pixmap*() functions to
drmmode_set_target_scanout_pixmap*() that take an additional parameter
PixmapPtr *target for explicitly setting different scanout pixmaps.
Add definitions for functions drmmode_SharedPixmapFlip(),
drmmode_SharedPixmapPresentOnVBlank(),
drmmode_SharedPixmapPresent(),
drmmode_SharedPixmapVBlankEventHandler(),
drmmode_SharedPixmapVBlankEventAbort(),
drmmode_EnableSharedPixmapFlipping(), and
drmmode_DisableSharedPixmapFlipping,
drmmode_InitSharedPixmapFlipping(), and
drmmode_FiniSharedPixmapFlipping, along with struct
vblank_event_args.
The control flow is as follows:
pScrPriv->rrEnableSharedPixmapFlipping() makes its way to
drmmode_EnableSharedPixmapFlipping(), which sets enable_flipping to
TRUE and sets both scanout pixmaps prime_pixmap and
prime_pixmap_back.
When setting a mode, if prime_pixmap is defined, modesetting
driver will call drmmode_InitSharedPixmapFlipping(), which if
flipping is enabled will call drmmode_SharedPixmapPresent() on
scanout_pixmap_back.
drmmode_SharedPixmapPresent() requests that for the source to
present on the given buffer using master->PresentSharedPixmap(). If
it succeeds, it will then attempt to flip to that buffer using
drmmode_SharedPixmapFlip(). Flipping shouldn't fail, but if it
does, it will raise a warning and try drmmode_SharedPixmapPresent()
again on the next vblank using
drmmode_SharedPixmapPresentOnVBlank().
master->PresentSharedPixmap() could fail, in most cases because
there is no outstanding damage on the mscreenpix tracked by the
shared pixmap. In this case, drmmode_SharedPixmapPresent() will
attempt to use master->RequestSharedPixmapNotifyDamage() to request
for the source driver to call slave->SharedPixmapNotifyDamage() in
response to damage on mscreenpix. This will ultimately call
into drmmode_SharedPixmapPresentOnVBlank() to retry
drmmode_SharedPixmapPresent() on the next vblank after
accumulating damage.
drmmode_SharedPixmapFlip() sets up page flip event handler by
packing struct vblank_event_args with the necessary parameters, and
registering drmmode_SharedPixmapVBlankEventHandler() and
drmmode_SharedPixmapVBlankEventAbort() with the modesetting DRM
event handler queue. Then, it uses the drmModePageFlip() to flip on
the next vblank and raise an event.
drmmode_SharedPixmapPresentOnVBlank() operates similarly to
drmmode_SharedPixmapFlip(), but uses drmWaitVBlank() instead of
drmModePageFlip() to raise the event without flipping.
On the next vblank, DRM will raise an event that will ultimately be
handled by drmmode_SharedPixmapVBlankEventHandler(). If we flipped,
it will update prime_pixmap and prime_pixmap_back to reflect that
frontTarget is now being displayed, and use
drmmode_SharedPixmapPresent(backTarget) to start the process again
on the now-hidden shared pixmap. If we didn't flip, it will just
use drmmode_SharedPixmapPresent(frontTarget) to start the process
again on the still-hidden shared pixmap.
Note that presentation generally happens asynchronously, so with
these changes alone tearing is reduced, but we can't always
guarantee that the present will finish before the flip. These
changes are meant to be paired with changes to the sink DRM driver
that makes flips wait on fences attached to dmabuf backed buffers.
The source driver is responsible for attaching the fences and
signaling them when presentation is finished.
Note that because presentation is requested in response to a
vblank, PRIME sources will now conform to the sink's refresh rate.
At teardown, pScrPriv->rrDisableSharedPixmapFlipping() will be
called, making its way to drmmode_FiniSharedPixmapFlipping().
There, the event handlers for prime_pixmap and prime_pixmap_back
are aborted, freeing the left over parameter structure. Then,
prime_pixmap and prime_pixmap back are unset as scanout pixmaps.
Register and tear down slave damage per-scanout pixmap instead of
per-crtc.
v1: Initial commit
v2: Renamed PresentTrackedFlippingPixmap to PresentSharedPixmap
Renamed flipSeq to flip_seq
Warn if flip failed
Use SharedPixmapNotifyDamage to retry on next vblank after damage
v3: Refactor to accomodate moving (rr)StartFlippingPixmapTracking and
(rr)(Enable/Disable)SharedPixmapFlipping to rrScrPrivRec from ScreenRec
Do damage tracking on both scanout pixmaps
v4: Tweaks to commit message
v5: Revise for internal storage of prime pixmap ptrs
Move disabling for reverse PRIME from source commit to here
Use drmmode_set_target_scanout_pixmap*() to set scanout pixmaps
internally to EnableSharedPixmapFlipping().
Don't support flipping if ms->drmmode.pageflip == FALSE.
Move flipping_active check to this commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
modesetting relied on randr_crtc->scanout_pixmap being consistent with
calls to SetScanoutPixmap, which is very fragile and makes a lot of
assumptions about the caller's behavior.
For example, RRReplaceScanoutPixmap(), when dropping off with !size_fits,
will set randr_crtc->scanout_pixmap = NULL and then call SetScanoutPixmap.
Without this patch, drmmode_set_scanout_pixmap_(cpu/gpu) will think that
there is no scanout pixmap to tear down, because it's already been set to
NULL.
By keeping track of the scanout pixmap in its internal state, modesetting
can avoid these types of bugs and reduce constraints on calling
conventions.
v1: N/A
v2: N/A
v3: N/A
v4: N/A
v5: Initial commit
v6: Rebase onto ToT
v7: Unchanged
Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
Both radeon and amdgpu don't set the mode until the first blockhandler,
this means everything should be rendered on the screen correctly by
then.
This ports this code, it also removes the tail call of EnterVT from
ScreenInit, it really isn't necessary and causes us to set a dirty mode
with -modesetting always anyways.
v2: reorder set desired modes vs block handler as done for amdgpu.
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This adds support using glamor for background None.
loosely based off the amdgpu code. relies on the glamor_finish code.
Acked-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This adds zaphod and ZaphodHeads support
to the the in-server modesetting driver.
this is based on a request from Mario,
and on the current radeon driver, along
with some patches from Mario to bring things
up to the state of the art in Zaphod.
v2: fixup vblank fd registring.
v3: squash Mario's fixes.
modesetting: Allow/Fix use of multiple ZaphodHead outputs per x-screen.
modesetting: Take shift in crtc positions for ZaphodHeads configs into account.
modesetting: Add ZaphodHeads description to man page.
small cleanups (airlied).
Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Based on code by Keith Packard, Eric Anholt, and Jason Ekstrand.
v2:
- Fix double free and flip_count underrun (caught by Mario Kleiner).
- Don't leak flip_vblank_event on the error_out path (Mario).
- Use the updated ms_flush_drm_events API (Mario, Ken).
v3: Hack around DPMS shenanigans. If all monitors are DPMS off, then
there is no active framebuffer; attempting to pageflip will hit the
error_undo paths, causing us to drmModeRmFB with no framebuffer,
which confuses the kernel into doing full modesets and generally
breaks things. To avoid this, make ms_present_check_flip check that
some CRTCs are enabled and DPMS on. This is an ugly hack that would
get better with atomic modesetting, or some core Present work.
v4:
- Don't do pageflipping if CRTCs are rotated (caught by Jason Ekstrand).
- Make pageflipping optional (Option "PageFlip" in xorg.conf.d), but
enabled by default.
v5: Initialize num_crtcs_on to 0 (caught by Michel Dänzer).
[airlied: took over]
v6: merge async flip support from Mario Kleiner
free sequence after failed vblank queue
handle unflip while DPMS'ed off (Michel)
move flip tracking into its own structure, and
fix up reference counting issues, and add comments.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Acked-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>