Commit Graph

7445 Commits

Author SHA1 Message Date
Olivier Fourdan
4cbf1fb1f9 xwayland: Avoid double free of RRCrtc and RROutput
At shutdown, the Xserver will free all its resources which includes the
RRCrtc and RROutput created.

Xwayland would do the same in its xwl_output_destroy() called from
xwl_close_screen(), leading to a double free of existing RRCrtc
RROutput:

 Invalid read of size 4
    at 0x4CDA10: RRCrtcDestroy (rrcrtc.c:689)
    by 0x426E75: xwl_output_destroy (xwayland-output.c:301)
    by 0x424144: xwl_close_screen (xwayland.c:117)
    by 0x460E17: CursorCloseScreen (cursor.c:187)
    by 0x4EB5A3: AnimCurCloseScreen (animcur.c:106)
    by 0x4EF431: present_close_screen (present_screen.c:64)
    by 0x556D40: dix_main (main.c:354)
    by 0x6F0D290: (below main) (in /usr/lib/libc-2.24.so)
  Address 0xbb1fc30 is 0 bytes inside a block of size 728 free'd
    at 0x4C2BDB0: free (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    by 0x4CCE5F: RRCrtcDestroyResource (rrcrtc.c:719)
    by 0x577541: doFreeResource (resource.c:895)
    by 0x5787B5: FreeClientResources (resource.c:1161)
    by 0x578862: FreeAllResources (resource.c:1176)
    by 0x556C54: dix_main (main.c:323)
    by 0x6F0D290: (below main) (in /usr/lib/libc-2.24.so)
  Block was alloc'd at
    at 0x4C2CA6A: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    by 0x4CC6DB: RRCrtcCreate (rrcrtc.c:76)
    by 0x426D1C: xwl_output_create (xwayland-output.c:264)
    by 0x4232EC: registry_global (xwayland.c:431)
    by 0x76CB1C7: ffi_call_unix64 (in /usr/lib/libffi.so.6.0.4)
    by 0x76CAC29: ffi_call (in /usr/lib/libffi.so.6.0.4)
    by 0x556CEFD: wl_closure_invoke (connection.c:935)
    by 0x5569CBF: dispatch_event.isra.4 (wayland-client.c:1310)
    by 0x556AF13: dispatch_queue (wayland-client.c:1456)
    by 0x556AF13: wl_display_dispatch_queue_pending
(wayland-client.c:1698)
    by 0x556B33A: wl_display_roundtrip_queue (wayland-client.c:1121)
    by 0x42371C: xwl_screen_init (xwayland.c:631)
    by 0x552F60: AddScreen (dispatch.c:3864)

And:

 Invalid read of size 4
    at 0x522890: RROutputDestroy (rroutput.c:348)
    by 0x42684E: xwl_output_destroy (xwayland-output.c:302)
    by 0x423CF4: xwl_close_screen (xwayland.c:118)
    by 0x4B6377: CursorCloseScreen (cursor.c:187)
    by 0x539503: AnimCurCloseScreen (animcur.c:106)
    by 0x53D081: present_close_screen (present_screen.c:64)
    by 0x43DBF0: dix_main (main.c:354)
    by 0x7068730: (below main) (libc-start.c:289)
  Address 0xc403190 is 0 bytes inside a block of size 154 free'd
    at 0x4C2CD5A: free (vg_replace_malloc.c:530)
    by 0x521DF3: RROutputDestroyResource (rroutput.c:389)
    by 0x45DA61: doFreeResource (resource.c:895)
    by 0x45ECFD: FreeClientResources (resource.c:1161)
    by 0x45EDC2: FreeAllResources (resource.c:1176)
    by 0x43DB04: dix_main (main.c:323)
    by 0x7068730: (below main) (libc-start.c:289)
  Block was alloc'd at
    at 0x4C2BBAD: malloc (vg_replace_malloc.c:299)
    by 0x52206B: RROutputCreate (rroutput.c:84)
    by 0x426763: xwl_output_create (xwayland-output.c:270)
    by 0x422EDC: registry_global (xwayland.c:432)
    by 0x740FC57: ffi_call_unix64 (unix64.S:76)
    by 0x740F6B9: ffi_call (ffi64.c:525)
    by 0x5495A9D: wl_closure_invoke (connection.c:949)
    by 0x549283F: dispatch_event.isra.4 (wayland-client.c:1274)
    by 0x5493A13: dispatch_queue (wayland-client.c:1420)
    by 0x5493A13: wl_display_dispatch_queue_pending
(wayland-client.c:1662)
    by 0x5493D2E: wl_display_roundtrip_queue (wayland-client.c:1085)
    by 0x4232EC: xwl_screen_init (xwayland.c:632)
    by 0x439F50: AddScreen (dispatch.c:3864)

Split xwl_output_destroy() into xwl_output_destroy() which frees the
wl_output and the xwl_output structure, and xwl_output_remove() which
does the RRCrtcDestroy() and RROutputDestroy() and call the latter only
when an output is effectively removed.

An additional benefit, on top of avoiding a double free, is to avoid
updating the screen size at shutdown.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
2016-08-15 14:20:54 -04:00
Olivier Fourdan
4d586118c1 xwayland: Plug memleak in frame callbacks
The frame callback set up via wl_surface_frame() needs to be freed with
wl_callback_destroy() or we'll leak memory.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97065
Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
2016-08-15 12:49:36 -04:00
Matthieu Herrb
611b3b1d40 Autoconfig: Fix the loop adding dectected drivers to the list of screens
This loop was written in a buggy style, causing a NULL driver ptr to be
passed to copyScreen(). copyScreen() only uses that to generate an
identifier string, so this is mostly harmless on systems that accept
NULL for asprintf() "%s" format. (the generated identifiers are off
by one wrt the driver names and the last one contains NULL.

For systems that don't accept NULL for '%s' this would cause a
segmentation fault when this code is used (no xorg.conf, but partial
config in xorg.conf.d for instance).

Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
Reviewed-by: Keith Packard <keithp@keithp.com>
2016-08-15 12:43:43 -04:00
Emily Deng
88820f1c7b xfree86: vgaarb: Initialize local variable rsrc_decodes
In function xf86VGAarbiterScrnInit when the "pEnt->bus.type" is
BUS_PLATFORM, the "pScrn->vgaDev" won't be set, so the "pScrn->vgaDev" is
equal to zero.

The variable "rsrc_decodes" in function "xf86VGAarbiterAllowDRI" is not
initialized. So it will occur error when "pScrn->vgaDev == 0", and
"vga_count > 1". For this case, as "pScrn->vgaDev == 0", the function
"pci_device_vgaarb_get_info" will only set the value of "vga_count",
but won't set the value of "rsrc_decodes", so it will has two different
return values for function "xf86VGAarbiterAllowDRI" in different
platforms. One platform will return TRUE, as the "rsrc_decodes" 's
default value is 0, but another platform will return FALSE, as the
"rsrc_decodes" 's default value is "32767", this will cause disable
direct rendering.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96937

Signed-off-by: Emily Deng <Emily.Deng@amd.com>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
2016-08-15 12:30:39 -04:00
Keith Packard
69b782aa75 xfree86: Set pScrn->pScreen before driver ScreenInit is called
Any code called from the driver ScreenInit may want to refer to
pScrn->pScreen. As the function passed to AddScreen is the first place
the DDX sees a new screen, the generic code needs to make sure that
value is set before passing control to the video driver's
initialization code.

This was found by running a driver which didn't bother to set this
value when the initial colormap was installed; xf86RandR12LoadPalette
tried to use pScrn->pScreen and crashed.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97124
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-and-Tested-by: Michel Dänzer <michel.daenzer@amd.com>
2016-08-13 09:18:15 -07:00
Peter Hutterer
f399919e13 xfree86: lock input during PreInit
This is a problem for the libinput driver that uses the same context across
multiple devices. The driver may be halfway through setting up an input device
(and the only way to do so is to add it to libinput) when the input thread
comes in an reads events. This then causes mayhem when data is dereferenced
that hasn't been set up yet.

In my case the cause was the call to libinput_path_remove_device() inside
preinit racing with evdev_dispatch_device() handling of ENODEV. The sequence
was:
- thread 2 gets an event and calls evdev_dispatch_device()
- thread 1 calls libinput_path_remove_device() which sets the device->source
  to NULL
- thread 2 reads from the fd, gets ENODEV and now removes the device->source,
  dereferencing the null-pointer

This is the one I could reproduce the most, but there are other potential
pitfalls that affect any driver that uses the same fd for multiple devices.
Avoid all this and wrap PreInit into the lock.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
2016-08-12 14:43:08 +10:00
Peter Hutterer
dd4e21cb3a xfree86: fix unbalanced input_lock/unlock in xf86NewInputDevice()
If a device couldn't be enabled we left the lock hanging.

This patch also removes the leftover OsReleaseSignals() call, now unnecessary.
Note that input_unlock() is later than previously OsReleaseSignals().
RemoveDevice() manipulates the input device and its file descriptors, it's
safer to put the input_unlock() call after RemoveDevice() to avoid events
coming in while the device is being removed.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
2016-08-12 14:41:19 +10:00
Michel Dänzer
a446ff84de xfree86/modes: Handle no palette case better in xf86RandR12CrtcSetGamma
Just use the RandR gamma ramp directly.

Fixes random on-monitor colours with drivers which don't call
xf86HandleColormaps, e.g. modesetting.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97154

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
2016-08-10 16:56:09 +09:00
Kenneth Graunke
d3d4ff0ed4 modesetting: Delete dead drmmode_bo_for_pixmap function.
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>
2016-08-08 23:42:40 -07:00
Michel Dänzer
b4e46c0444 xfree86: Hook up colormaps and RandR 1.2 gamma code v6
Instead of breaking the former when the driver supports the latter,
hook them up so that the hardware LUTs reflect the combination of the
current colourmap and gamma states. I.e. combine the colourmap, the
global gamma value/ramp and the RandR 1.2 per-CRTC gamma ramps into one
combined LUT per CRTC.

Fixes e.g. gamma sliders not working in games.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=27222

v2:
* Initialize palette_size and palette struct members, fixes crash on
  server startup.
v3:
* Free randrp->palette in xf86RandR12CloseScreen, fixes memory leak.
v4:
* Call CMapUnwrapScreen if xf86RandR12InitGamma fails (Emil Velikov).
* Still allow xf86HandleColormaps to be called with a NULL loadPalette
  parameter in the xf86_crtc_supports_gamma case.
v5:
* Clean up inner loops in xf86RandR12CrtcComputeGamma (Keith Packard)
* Move palette update out of per-CRTC loop in xf86RandR12LoadPalette
  (Keith Packard)
v6:
* Handle reallocarray failure in xf86RandR12LoadPalette (Keith Packard)

Reviewed-by: Keith Packard <keithp@keithp.com>
2016-07-28 10:12:05 +09:00
Michel Dänzer
17213b74fd xfree86/modes: Remove xf86RandR12CrtcGetGamma
This would normally return the same values the core RandR code passed to
xf86RandR12CrtcSetGamma before, which is rather pointless. The only
possible exception would be if a driver tried initializing
crtc->gamma_red/green/blue to reflect the hardware LUT state on startup,
but that can't work correctly if whatever set the LUT before the server
started was running at a different depth.

Even the pointless round-trip case will no longer work with the
following change.

Reviewed-by: Keith Packard <keithp@keithp.com>
2016-07-28 10:11:14 +09:00
Michel Dänzer
62f4405257 xfree86/modes: Move gamma initialization to xf86RandR12Init12 v2
RRCrtcGammaSetSize cannot be used yet in xf86InitialConfiguration,
because randr_crtc isn't allocated yet at that point, but a following
change will require RRCrtcGammaSetSize to be called from
xf86RandR12CrtcInitGamma.

v2:
* Bail from xf86RandR12CrtcInitGamma if !crtc->funcs->gamma_set (Keith
  Packard)

Reviewed-by: Keith Packard <keithp@keithp.com>
2016-07-27 17:49:39 +09:00
Keith Packard
d403aca70a Switch poll() users to xserver_poll()
This uses the wrapper in case we need to emulate poll with select
as we do on Windows.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
2016-07-21 15:04:36 -04:00
Jon Turney
2a79be9e4d hw/xwin: Update BlockHandler function signature
Update for removal of fdset from Block/Wakeup handler API in 9d15912a

Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
Reviewed-by: Keith Packard <keithp@keithp.com>
2016-07-19 08:10:11 -07:00
Jon Turney
60a91031d1 hw/xwin: Update for removal of AddEnabledDevice
Update for removal of AddEnabledDevice in be5a513f. Use SetNotifyFd instead.

Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
Reviewed-by: Keith Packard <keithp@keithp.com>
2016-07-19 08:10:03 -07:00
Peter Hutterer
7f2d690725 xfree86: if ATTR_KEYBOARD is set, match for keyboards
ATTR_KEY maps to ID_INPUT_KEY which is set for any device with keys.
ID_INPUT_KEYBOARD and thus ATTR_KEYBOARD is set for devices that are actual
keyboards (and have a set of expected keys).

Hand-written match rules may only apply ID_INPUT_KEYBOARD, so make sure we
match on that too.

Arguably we should've been matching on ATTR_KEYBOARD only all along but
changing that likely introduces regressions.

Reported-by: Marty Plummer <netz.kernel@gmail.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2016-07-18 16:40:46 -04:00
Adam Jackson
4b311d23e8 modesetting: resubmit dirty rects on EINVAL (v2)
This error code can mean we're submitting more rects at once than the
driver can handle. If that happens, resubmit one at a time.

v2: Make the rect submit loop more error-proof (Walter Harms)

Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Michael Thayer <michael.thayer@oracle.com>
2016-07-18 16:35:16 -04:00
Keith Packard
4af00242ef Bump ABI versions to reflect block/wakeup handler API changes
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:27:51 -04:00
Keith Packard
9d15912aa4 Remove fd_set from Block/Wakeup handler API
This removes the last uses of fd_set from the server interfaces
outside of the OS layer itself.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:27:51 -04:00
Keith Packard
fb0802113b Remove readmask from screen block/wakeup handler
With no users of the interface needing the readmask anymore, we can
remove it from the argument passed to these functions.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:27:51 -04:00
Keith Packard
410bc04748 dmx: Eliminate use of AddEnabledDevice [v2]
Use SetNotifyFd instead, with the hope that someday someone will come
fix this to be more efficient -- right now, the wakeup handler is
doing the event reading, instead of the notify callback.

v2: no need to patch dmxsigio.c as it has been removed.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
2016-07-18 15:27:42 -04:00
Keith Packard
6299ef3d74 modesetting: Use passed-in fd for drm event monitoring NotifyFd callback
This is a cleanup, proposed by Adam Jackson, but wasn't merged with
the original NotifyFD changes.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
6bf7b49f67 hw/kdrive: Use passed-in fd for kdrive/linux APM monitoring [v2]
This is a cleanup, proposed by Adam Jackson, but wasn't merged with
the original NotifyFD changes.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
55c2e1a3aa xnest: Use SetNotifyFd to receive events
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
24e65bf0db hw/xfree86: Use NotifyFd for other input fd wakeups
Remove code in xf86Wakeup for dealing with other input and switch to
using the new NotifyFd interface.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
559aac2d71 dmx: Switch from select(2) to poll(2) for input
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
aa6717ce21 xfree86: Switch from select(2) to poll(2)
xf86WaitForInput and the xf86 SIGIO handling code.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
81135991a5 kdrive: switch from select(2) to poll(2)
This avoids fd limits

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Keith Packard
05a793f5b3 dix: Switch to the libXfont2 API (v2)
This new libXfont API eliminates exposing internal X server symbols to
the font library, replacing those with a struct full of the entire API
needed to use that library.

v2: Use libXfont2 instead of libXfont_2

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
2016-07-18 15:25:59 -04:00
Adam Jackson
32a9504c69 xfree86: Fix fallback driver sort order for Xorg -configure (v2)
The intent here was that fallback drivers would be at the end of the
list in order, but if a fallback driver happened to be at the end of the
list already that's not what would happen. Rather than open-code
something smarter, just use qsort.

Note that qsort puts things in ascending order, so somewhat backwardsly
fallbacks are greater than native drivers, and vesa is greater than
modesetting.

v2: Use strcmp to compare non-fallback drivers so we get a predictable
result if your libc's qsort isn't stable (Keith Packard)

Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Adam Jackson <ajax@redhat.com>
2016-07-15 11:08:01 -04:00
Adam Jackson
9fcb554e9b xwayland: Only force monotonic clock once
Otherwise on regeneration we get:

(EE) BUG: triggered 'if (clockid)'
(EE) BUG: utils.c:440 in ForceClockId()
(EE)
(EE) Backtrace:
(EE) 0: ./hw/xwayland/Xwayland (ForceClockId+0x5c) [0x47713c]
(EE) 1: ./hw/xwayland/Xwayland (OsInit+0x25) [0x4763d5]
(EE) 2: ./hw/xwayland/Xwayland (dix_main+0x11c) [0x43e60c]
(EE) 3: /lib64/libc.so.6 (__libc_start_main+0xf1) [0x7f627b2f9731]
(EE) 4: ./hw/xwayland/Xwayland (_start+0x29) [0x4238e9]
(EE) 5: ? (?+0x29) [0x29]

Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Jonas Ådahl <jadahl@gmail.com>
2016-07-15 10:09:24 -04:00
Rui Matos
cf6730c503 xwayland: Update RR state on wl_output.done instead of wl_output.mode
Otherwise if the geometry changes but the mode doesn't we end up with
the previous geometry from RR's point of view.

Fixes https://bugzilla.gnome.org/show_bug.cgi?id=768710

Reviewed-by: Jonas Ådahl <jadahl@gmail.com>
Signed-off-by: Rui Matos <tiagomatos@gmail.com>
2016-07-15 10:03:16 -04:00
Hans De Goede
033888e776 linux: Do not try to open /dev/vc/0, fix error msg when /dev/tty0 open fails
/dev/vc/0 is a devfs thing which is long dead, so stop trying to open
/dev/vc/0, besides being a (small) code cleanup this will also fix the
"parse_vt_settings: Cannot open /dev/tty0 (%s)\n" error message to
display the actual error, rather then the -ENOENT from also trying
/dev/vc/0.

BugLink: https://patchwork.freedesktop.org/patch/8768/
Reported-by: Chad Versace <chad.versace@linux.intel.com>
Suggested-by: Julien Cristau <jcristau@debian.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Julien Cristau <jcristau@debian.org>
Reviewed-by: Chad Versace <chad.versace@intel.com>
2016-07-08 13:43:25 -04:00
Alex Goins
ce24f3aa58 modesetting: NULL assignment for drmmode_set_target_scanout_target_cpu
Commit 80e64dae: "modesetting: Implement PRIME syncing as a sink" originally was
supposed to have this line, but it was dropped as part of the merge process.

Foregoing the NULL assignment causes a ton of problems with dereferencing
uninitialized memory.

Signed-off-by: Alex Goins <agoins@nvidia.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2016-07-08 13:40:15 -04:00
Hans de Goede
60ad701a6a modesetting: Load on GPU-s with 0 outputs
In newer laptops with switchable graphics, the GPU may have 0 outputs,
in this case the modesetting driver should still load if the GPU is
SourceOffload capable, so that it can be used as an offload source provider.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
2016-07-02 09:54:07 +02:00
Hans de Goede
94a1c77259 modesetting: Fix swapping of provider sink / source capabilities
When a card has import capability it can be an offload _sink_, not
a source and vice versa for export capability.

This commit fixes the modesetting driver to properly set these
capabilities, this went unnoticed sofar because most gpus have both
import and export capability.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
2016-07-02 09:54:07 +02:00
Adam Jackson
fcbafdfd79 modesetting: Implement a double-buffered shadow mode
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>
2016-07-02 09:54:07 +02:00
Adam Jackson
75e660e379 modesetting: Drop some non-functional triple-buffering variables
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>
2016-07-02 09:28:04 +02:00
Dave Airlie
21217d0216 modesetting: Implement 32->24 bpp conversion in shadow update
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>
2016-07-02 09:28:04 +02:00
Takashi Iwai
af916477c6 modesetting: Fix hw cursor check at the first call
With the previous patch, the modesetting driver can now return whether
the driver supports hw cursor.  However, it alone doesn't suffice,
unfortunately. drmmode_load_cursor_argb_check() is called in the
following chain:

  xf86CursorSetCursor()
    -> xf86SetCursor()
       -> xf86DriverLoadCursorARGB()
         -> xf86_load_cursor_argb()
           -> xf86_crtc_load_cursor_argb()
             -> drmmode_load_cursor_argb_check()

*but* at first with drmmode_crtc->cursor_up = FALSE.  Then the
function doesn't actually set the cursor but returns TRUE
unconditionally.  The actual call of drmmode_set_cursor() is done at
first via the show_cursor callback, and there is no check of sw cursor
fallback any longer at this place. Since it's called only once per
cursor setup, so the xserver still thinks as if the hw cursor is
supported.

This patch is an ad hoc fix to correct the behavior somehow: it does
call drmmode_set_cursor() at the very first time even if cursor_up is
FALSE, then quickly hides again.  In that way, whether the hw cursor
is supported is evaluated in the right place at the right time.

Of course, it might be more elegant if we have a more proper mechanism
to fall back to sw cursor at any call path.  But it'd need more
rework, so I leave this workaround as is for now.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Adam Jackson <ajax@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-07-02 09:26:11 +02:00
Takashi Iwai
14c21ea1c9 modesetting: Use load_cursor_argb_check for sw cursor fallback
The modesetting driver still has an everlasting bug of invisible
cursor on cirrus and other KMS drivers where no hardware cursor is
supported.  This patch is a part of an attempt to address it.

This patch particularly converts the current load_cursor_argb callback
of modesetting driver to load_cursor_argb_check so that it can return
whether the driver handles the hw cursor or falls back to the sw
cursor.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
[hdegoede@redhat.com: Add extra comment suggested by Kenneth]
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-07-01 19:08:20 +02:00
Takashi Iwai
074cf58769 modesetting: Fix the error check from DRM_IOCTL_MODE_CURSOR2
The error value isn't always -EINVAL, e.g. the kernel drm core returns
-ENXIO when the corresponding ops doesn't exist.  Without this fix,
DRM_IOCTL_MODE_CURSOR2 would be dealt as success even if it
shouldn't.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
2016-07-01 19:08:20 +02:00
Alex Goins
b83dede9cb modesetting: Implement PRIME syncing as a source
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>
2016-06-28 12:56:45 -04:00
Alex Goins
44cb9578c0 modesetting: Disable Reverse PRIME for i915
Reverse PRIME seems to be designed with discrete graphics as a sink in
mind, designed to do an extra copy from sysmem to vidmem to prevent a
discrete chip from needing to scan out from sysmem.

The criteria it used to detect this case is if we are a GPU screen and
Glamor accelerated. It's possible for i915 to fulfill these conditions,
despite the fact that the additional copy doesn't make sense for i915.

Normally, you could just set AccelMethod = none as an option for the device
and call it a day. However, when running with modesetting as both the sink
and the source, Glamor must be enabled.

Ideally, you would be able to set AccelMethod individually for devices
using the same driver, but there seems to be a bug in X option parsing that
makes all devices on a driver inherit the options from the first detected
device. Thus, glamor needs to be enabled for all or for none until that bug
(if it's even a bug) is fixed.

Nonetheless, it probably doesn't make sense to do the extra copy on i915
even if Glamor is enabled for the device, so this is more user friendly by
not requiring users to disable acceleration for i915.

v1: N/A
v2: N/A
v3: N/A
v4: Initial commit
v5: Unchanged
v6: Rebase onto ToT
v7: NULL check and free drmVersionPtr

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:43 -04:00
Alex Goins
f6fef2a171 modesetting: Blacklist USB transport devices from PRIME sync
UDL (USB 2.0 DisplayLink DRM driver) and other drivers for USB transport devices
have strange semantics when it comes to vblank events, due to their inability to
get the actual vblank info.

When doing a page flip, UDL instantly raises a vblank event without waiting for
vblank. It also has no support for DRM_IOCTL_WAIT_VBLANK, and has some strange
behavior with how it handles damage when page flipping.

It's possible to get something semi-working by hacking around these issues,
but even then there isn't much value-add vs single buffered PRIME, and it
reduces maintainability and adds additional risks to the modesetting driver
when running with more well-behaved DRM drivers.

Work needs to be done on UDL in order to properly support synchronized
PRIME. For now, just blacklist it, causing RandR to fall back to
unsynchronized PRIME.

This patch originally blacklisted UDL by name, but it was pointed out that there
are other USB transport device drivers with similar limitations, so it was
expanded to blacklist all USB transport devices.

v1: N/A
v2: N/A
v3: Initial commit
v4: Move check to driver.c for consistency/visibility
v5: Refactor to accomodate earlier changes
v6: Rebase onto ToT
v7: Expand to blacklist all USB transport devices, not just UDL

Signed-off-by: Alex Goins <agoins@nvidia.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Reviewed-by: Dave Airlie <airlied@redhat.com>
2016-06-28 12:56:37 -04:00
Alex Goins
500853086d modesetting: Suspend and resume flipping with DPMS
DPMS would prevent page flip / vblank events from being raised, freezing
the screen until PRIME flipping was reinitialized. To handle DPMS cleanly,
suspend PRIME page flipping when DPMS mode is not on, and resume it when
DPMS mode is on.

v1: Initial commit
v2: Moved flipping_active check from previous commit to here
v3: Unchanged
v4: Unchanged
v5: Move flipping_active check to sink support commit
v6: Rebase onto ToT
v7: Unchanged

Reviewed-by: Dave Airlie <airlied@redhat.com>
Signed-off-by: Alex Goins <agoins@nvidia.com>
2016-06-28 12:56:35 -04:00
Alex Goins
80e64dae8a modesetting: Implement PRIME syncing as a sink
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>
2016-06-28 12:56:30 -04:00
Alex Goins
378c85a884 modesetting: Always load ms->drmmode.pageflip
ms->drmmode.pageflip was only loaded from options if ms->drmmode.glamor was
defined, otherwise it would always assume FALSE.

PRIME Synchronization requires ms->drmmode.pageflip even if we aren't using
glamor, so load it unconditionally.

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>
2016-06-28 12:56:27 -04:00
Alex Goins
b773a9c812 modesetting: Always tear down scanout pixmap
drmmode_set_scanout_pixmap_(cpu/gpu) would only do teardown if ppix ==
NULL. This meant that if there were consecutive calls to
SetScanoutPixmap(ppix != NULL) without calls to SetScanoutPixmap(ppix ==
NULL) in between, earlier calls would be leaked.  RRReplaceScanoutPixmap()
does this today.

Instead, when setting a scanout pixmap, always do teardown of the existing
scanout pixmap before setting up the new one. Then, if there is no new one
to set up, stop there.

This maintains the previous behavior in all cases except those with
multiple consecutive calls to SetScanoutPixmap(ppix != NULL).

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>
2016-06-28 12:56:25 -04:00
Alex Goins
f4c37eeee7 modesetting: Internal storage of scanout pixmaps
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>
2016-06-28 12:56:21 -04:00