[PATCH] xfree86: Remove redundant ServerIsNotSeat0 check from xf86CallDriverProbe
If foundScreen is TRUE, then all the code below the removed if will not execute until we reach the return foundScreen; at the end, so this entire if block is redundant. Signed-off-by: Hans de Goede --- hw/xfree86/common/xf86Bus.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c index 5b93940..27c6b1b 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -82,8 +82,6 @@ xf86CallDriverProbe(DriverPtr drv, Bool detect_only) if (!xf86DoConfigure && drv->platformProbe != NULL) { foundScreen = xf86platformProbeDev(drv); } -if (ServerIsNotSeat0() && foundScreen) -return foundScreen; #endif #ifdef XSERVER_LIBPCIACCESS -- 2.9.3 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH 1/2] xfree86: Make adding unclaimed devices as GPU devices a separate step
This is primarily a preparation patch for fixing the xserver exiting with a "no screens found" error even though there are supported video cards, due to the server not recognizing any card as the primary card. This also fixes the (mostly theoretical) case of a platformBus capable driver adding a device as GPUscreen before a driver which only supports the old PCI probe method gets a chance to claim it as a normal screen. Signed-off-by: Hans de Goede --- hw/xfree86/common/xf86Bus.c | 4 hw/xfree86/common/xf86platformBus.c | 15 +++ hw/xfree86/common/xf86platformBus.h | 6 ++ 3 files changed, 25 insertions(+) diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c index 27c6b1b..a3a9898 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -125,6 +125,10 @@ xf86BusConfig(void) xf86CallDriverProbe(xf86DriverList[i], FALSE); } +for (i = 0; i < xf86NumDrivers; i++) { +xf86platformAddGPUDevices(xf86DriverList[i]); +} + /* If nothing was detected, return now */ if (xf86NumScreens == 0) { xf86Msg(X_ERROR, "No devices detected.\n"); diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index 3e2264f..ec2a1dd 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -476,6 +476,21 @@ xf86platformProbeDev(DriverPtr drvp) isGPUDevice(devList[i]) ? PLATFORM_PROBE_GPU_SCREEN : 0); } +return foundScreen; +} + +int +xf86platformAddGPUDevices(DriverPtr drvp) +{ +Bool foundScreen = FALSE; +GDevPtr *devList; +int j; + +if (!drvp->platformProbe) +return FALSE; + +xf86MatchDevice(drvp->driverName, &devList); + /* if autoaddgpu devices is enabled then go find any unclaimed platform * devices and add them as GPU screens */ if (xf86Info.autoAddGPU) { diff --git a/hw/xfree86/common/xf86platformBus.h b/hw/xfree86/common/xf86platformBus.h index a7335b9..0f5c0ef 100644 --- a/hw/xfree86/common/xf86platformBus.h +++ b/hw/xfree86/common/xf86platformBus.h @@ -41,6 +41,7 @@ struct xf86_platform_device { #ifdef XSERVER_PLATFORM_BUS int xf86platformProbe(void); int xf86platformProbeDev(DriverPtr drvp); +int xf86platformAddGPUDevices(DriverPtr drvp); extern int xf86_num_platform_devices; extern struct xf86_platform_device *xf86_platform_devices; @@ -156,6 +157,11 @@ xf86PlatformMatchDriver(char *matches[], int nmatches); extern void xf86platformVTProbe(void); extern void xf86platformPrimary(void); + +#else + +static inline int xf86platformAddGPUDevices(DriverPtr drvp) { return FALSE; } + #endif #endif -- 2.9.3 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH 2/2] xfree86: Try harder to find atleast 1 non GPU Screen
If we did not find any non GPU Screens, try again ignoring the notion of any video devices being the primary device. This fixes Xorg exiting with a "no screens found" error when using virtio-vga in a virtual-machine and when using a device driven by simpledrm. This is a somewhat ugly solution, but it is the best I can come up with without major surgery to the bus and probe code. Signed-off-by: Hans de Goede --- hw/xfree86/common/xf86.h| 1 + hw/xfree86/common/xf86Bus.c | 26 +++--- hw/xfree86/common/xf86Globals.c | 1 + hw/xfree86/common/xf86pciBus.c | 4 hw/xfree86/common/xf86platformBus.c | 4 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index e54c811..f724688 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -55,6 +55,7 @@ extern _X_EXPORT int xf86DoConfigure; extern _X_EXPORT int xf86DoShowOptions; extern _X_EXPORT Bool xf86DoConfigurePass1; +extern _X_EXPORT Bool xf86ProbeIgnorePrimary; extern _X_EXPORT Bool xorgHWAccess; extern _X_EXPORT DevPrivateKeyRec xf86ScreenKeyRec; diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c index a3a9898..9836803 100644 --- a/hw/xfree86/common/xf86Bus.c +++ b/hw/xfree86/common/xf86Bus.c @@ -117,14 +117,34 @@ xf86BusConfig(void) int i, j; /* - * Now call each of the Probe functions. Each successful probe will - * result in an extra entry added to the xf86Screens[] list for each - * instance of the hardware found. + * 3 step probe to (hopefully) ensure that we always find at least 1 + * (non GPU) screen: + * + * 1. Call each drivers probe function normally, + *Each successful probe will result in an extra entry added to the + *xf86Screens[] list for each instance of the hardware found. */ for (i = 0; i < xf86NumDrivers; i++) { xf86CallDriverProbe(xf86DriverList[i], FALSE); } +/* + * 2. If no Screens were found, call each drivers probe function with + *ignorePrimary = TRUE, to ensure that we do actually get a + *Screen if there is atleast one supported video card. + */ +if (xf86NumScreens == 0) { +xf86ProbeIgnorePrimary = TRUE; +for (i = 0; i < xf86NumDrivers && xf86NumScreens == 0; i++) { +xf86CallDriverProbe(xf86DriverList[i], FALSE); +} +xf86ProbeIgnorePrimary = FALSE; +} + +/* + * 3. Call xf86platformAddGPUDevices() to add any additional video cards as + *GPUScreens (GPUScreens are only supported by platformBus drivers). + */ for (i = 0; i < xf86NumDrivers; i++) { xf86platformAddGPUDevices(xf86DriverList[i]); } diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c index 072c3fc..0d1e31b 100644 --- a/hw/xfree86/common/xf86Globals.c +++ b/hw/xfree86/common/xf86Globals.c @@ -153,6 +153,7 @@ XF86ConfigPtr xf86configptr = NULL; Bool xf86Resetting = FALSE; Bool xf86Initialising = FALSE; Bool xf86DoConfigure = FALSE; +Bool xf86ProbeIgnorePrimary = FALSE; Bool xf86DoShowOptions = FALSE; DriverPtr *xf86DriverList = NULL; int xf86NumDrivers = 0; diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c index 8158c2b..9adfee5 100644 --- a/hw/xfree86/common/xf86pciBus.c +++ b/hw/xfree86/common/xf86pciBus.c @@ -352,6 +352,10 @@ xf86ComparePciBusString(const char *busID, int bus, int device, int func) Bool xf86IsPrimaryPci(struct pci_device *pPci) { +/* Add max. 1 screen for the IgnorePrimary fallback path */ +if (xf86ProbeIgnorePrimary && xf86NumScreens == 0) +return TRUE; + if (primaryBus.type == BUS_PCI) return pPci == primaryBus.id.pci; #ifdef XSERVER_PLATFORM_BUS diff --git a/hw/xfree86/common/xf86platformBus.c b/hw/xfree86/common/xf86platformBus.c index ec2a1dd..fde6796 100644 --- a/hw/xfree86/common/xf86platformBus.c +++ b/hw/xfree86/common/xf86platformBus.c @@ -115,6 +115,10 @@ xf86_find_platform_device_by_devnum(int major, int minor) static Bool xf86IsPrimaryPlatform(struct xf86_platform_device *plat) { +/* Add max. 1 screen for the IgnorePrimary fallback path */ +if (xf86ProbeIgnorePrimary && xf86NumScreens == 0) +return TRUE; + if (primaryBus.type == BUS_PLATFORM) return plat == primaryBus.id.plat; #ifdef XSERVER_LIBPCIACCESS -- 2.9.3 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver] os/xdmcp: Honour -once when session is dead
Terminate a dead session when -once was passed. Don't restart it. Signed-off-by: Daniel Martin --- os/xdmcp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/os/xdmcp.c b/os/xdmcp.c index 906c959..7aeb393 100644 --- a/os/xdmcp.c +++ b/os/xdmcp.c @@ -797,7 +797,7 @@ XdmcpDeadSession(const char *reason) ErrorF("XDM: %s, declaring session dead\n", reason); state = XDM_INIT_STATE; isItTimeToYield = TRUE; -dispatchException |= DE_RESET; +dispatchException |= (OneSession ? DE_TERMINATE : DE_RESET); TimerCancel(xdmcp_timer); timeOutRtx = 0; send_packet(); -- 2.10.0 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver] glamor: Accelerate XYBitmap PutImage
XYBitmap to a drawable of depth != 1 is special. Where bits are 1, we draw the foreground color; where they are 0, we draw the background color. To handle this without falling back, allocate a temporary pixmap, do the color expansion in software, and then upload that image to the destination. This could probably be made faster if GL exposed an R1 texture format. Signed-off-by: Adam Jackson --- glamor/glamor_image.c | 40 1 file changed, 40 insertions(+) diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c index 3158749..699bdb8 100644 --- a/glamor/glamor_image.c +++ b/glamor/glamor_image.c @@ -24,6 +24,33 @@ #include "glamor_transfer.h" #include "glamor_transform.h" +static PixmapPtr +glamor_expand_bitmap(DrawablePtr drawable, GCPtr src, int w, int h, char *bits) +{ +ScreenPtr screen = drawable->pScreen; +PixmapPtr ret; +GCPtr gc; +ChangeGCVal v[2]; + +if (!(gc = GetScratchGC(drawable->depth, screen))) +return NULL; + +ret = screen->CreatePixmap(screen, w, h, drawable->depth, + GLAMOR_CREATE_PIXMAP_CPU); + +if (ret) { +DrawablePtr scratch = &ret->drawable; +v[0].val = src->fgPixel; +v[1].val = src->bgPixel; +ChangeGC(serverClient, gc, GCForeground | GCBackground, v); +ValidateGC(scratch, gc); +fbPutImage(scratch, gc, gc->depth, 0, 0, w, h, 0, XYBitmap, bits); +} + +FreeScratchGC(gc); +return ret; +} + /* * PutImage. Only does ZPixmap right now as other formats are quite a bit harder */ @@ -35,6 +62,7 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); +PixmapPtr tmp = NULL; glamor_pixmap_private *pixmap_priv; uint32_tbyte_stride = PixmapBytePad(w, drawable->depth); RegionRec region; @@ -55,6 +83,14 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, if (format == XYPixmap && drawable->depth == 1 && leftPad == 0) format = ZPixmap; +if (format == XYBitmap && leftPad == 0) { +if (!(tmp = glamor_expand_bitmap(drawable, gc, w, h, bits))) +goto bail; + +bits = tmp->devPrivate.ptr; +format = ZPixmap; +} + if (format != ZPixmap) goto bail; @@ -79,6 +115,10 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, glamor_upload_region(pixmap, ®ion, x, y, (uint8_t *) bits, byte_stride); RegionUninit(®ion); + +if (tmp) +fbDestroyPixmap(tmp); + return TRUE; bail: return FALSE; -- 2.9.3 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH] glamor: spans: fixup wrong count on glDrawArrays
Mark Yao writes: > since commit (9e9fcf5 glamor: Add a helper function for the common > GL_QUADS fallback pattern.), the glDrawArrays count change to nbox, > That is wrong, I think it maybe cause by fat finger. > > Signed-off-by: Mark Yao Thanks! This fixes xlogo on a GL 2.1 implementation. I need to rig up testing for 2.1 specifically -- we've had plenty of breakage on it at this point. signature.asc Description: PGP signature ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH xserver] modesetting: always set a hardware cursor when requested to load one.
Hello Hans, On 29.09.2016 09:56, Hans de Goede wrote: Hi, On 28-09-16 16:54, Michael Thayer wrote: Hello Hans, On 28.09.2016 15:37, Hans de Goede wrote: Hi Michael, On 28-09-16 14:47, Michael Thayer wrote: [...] On 09/16/2016 06:52 PM, Michael Thayer wrote: When the X server asks us to load a hardware cursor, that request is always followed up by a request to show it if we report success, or to hide it if we report failure. Therefore it makes no sense to suppress the request if the cursor is not currently visible. [...] For the record, I looked at making show_cursor() return a boolean. It seemed feasible, and would allow for removing the first time hack in modesetting too Making show_cursor return an error (adding a show_cursor_check()) seems to be the best solution to me, we actually had a patch submitted for this, but it was deemed unnecessary. I guess it is necessary after all: https://patchwork.freedesktop.org/patch/94495/ but there was a catch in that the cursor could theoretically be visible but still hidden on all screens (with a strange screen layout), Yes that is possible. in which case show_cursor() would not be called until the cursor moved onto a screen. Ack. Making set_cursor_position() return a success value seemed a bit too invasive. But in the scenario you describe it is not the drivers set_cursor_position() which will get called (well not only) also the drivers' show_cursor will get called on the crtc where the cursor should now show, so just making show_cursor return an error should be enough. [...] Right, xf86_crtc_set_cursor_position() calls the driver's show_cursor(). What I meant was that that means that this function can now fail, and that failure needs to be propagated up and probably handled in xf86CursorMoveCursor() by reverting to a software cursor there. The alternative is another first time-style hack (if we are asked to show the cursor and it is not in range of any of the crtc-s then flicker it). Hmm, so 2 things: 1) We definitely do not want another first-time hack, so if we really need to lets do the propagate error thing 2) Thinking about holes in crtc layouts again, I think the xrandr cursor constraint code will warp the pointer to the closest crtc then (pretty sure actually) so I think this is a non issue. So just rebasing the patch I linked (and dropping the first time hack) should be enough. And since we're planning to do this for 1.20, I think we should just try doing things that way, we've an entire cycle to catch any issues then (which I do not believe there will be) I rebased Alexandre's patch (not sure if there is an official way to credit someone, I just did so in the commit message) as two new patches, one to xfree86 and one to modesetting (in which I also got rid of the first time hack), both slightly adjusted to be more like existing code. I rebased my software-back-to-hardware on top of that. I did not follow all code paths in detail, but it does look to me as if what you said about the constraint code is what is intended (can someone who knows RandR confirm?), so that if it does not work then it is the constraint code which should be fixed. I tested that switching to a software cursor happens as soon as drmmode_show_cursor() is called, that the test for hardware cursor support is repeated on every show or set call, and although I can't confirm visually (we only have a single hardware cursor, not one per crtc), I checked as best I could using break-points in gdb that showing and hiding cursors happened correctly on multiple screens. Feel free to suggest additional tests. Patches coming up. Regards, Michael Regards, Hans Regards, Michael -- Michael Thayer | VirtualBox engineer ORACLE Deutschland B.V. & Co. KG | Werkstr. 24 | D-71384 Weinstadt ORACLE Deutschland B.V. & Co. KG Hauptverwaltung: Riesstraße 25, D-80992 München Registergericht: Amtsgericht München, HRA 95603 Komplementärin: ORACLE Deutschland Verwaltung B.V. Hertogswetering 163/167, 3543 AS Utrecht, Niederlande Handelsregister der Handelskammer Midden-Nederland, Nr. 30143697 Geschäftsführer: Alexander van der Ven, Jan Schultheiss, Val Maher ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver 1/3] xfree86: Immediately handle failure to set HW cursor, v5
Based on v4 by Alexandre Courbot 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: Updated the patch to apply to current git HEAD, split up into two patches (server and modesetting driver) and adjusted the code slightly to match surrounding code. I also removed the new exported function ShowCursorCheck(), as instead just changing ShowCursor() to return Bool should not affect its current callers. Signed-off-by: Michael Thayer --- hw/xfree86/modes/xf86Crtc.h| 4 +++- hw/xfree86/modes/xf86Cursors.c | 40 ++-- hw/xfree86/ramdac/xf86Cursor.h | 16 hw/xfree86/ramdac/xf86HWCurs.c | 8 4 files changed, 53 insertions(+), 15 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index 14ba9d7..215eb2a 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -195,6 +195,8 @@ typedef struct _xf86CrtcFuncs { */ void (*show_cursor) (xf86CrtcPtr crtc); +Bool + (*show_cursor_check) (xf86CrtcPtr crtc); /** * Hide cursor @@ -993,7 +995,7 @@ static _X_INLINE _X_DEPRECATED void xf86_reload_cursors(ScreenPtr screen) {} /** * Called from EnterVT to turn the cursors back on */ -extern _X_EXPORT void +extern _X_EXPORT Bool xf86_show_cursors(ScrnInfoPtr scrn); /** diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c index 1bc2b27..9543eed 100644 --- a/hw/xfree86/modes/xf86Cursors.c +++ b/hw/xfree86/modes/xf86Cursors.c @@ -210,9 +210,15 @@ set_bit(CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask) /* * Wrappers to deal with API compatibility with drivers that don't expose - * load_cursor_*_check + * *_cursor_*_check */ static inline Bool +xf86_driver_has_show_cursor(xf86CrtcPtr crtc) +{ +return crtc->funcs->show_cursor_check || crtc->funcs->show_cursor; +} + +static inline Bool xf86_driver_has_load_cursor_image(xf86CrtcPtr crtc) { return crtc->funcs->load_cursor_image_check || crtc->funcs->load_cursor_image; @@ -225,6 +231,15 @@ xf86_driver_has_load_cursor_argb(xf86CrtcPtr crtc) } static inline Bool +xf86_driver_show_cursor(xf86CrtcPtr crtc) +{ +if (crtc->funcs->show_cursor_check) +return crtc->funcs->show_cursor_check(crtc); +crtc->funcs->show_cursor(crtc); +return TRUE; +} + +static inline Bool xf86_driver_load_cursor_image(xf86CrtcPtr crtc, CARD8 *cursor_image) { if (crtc->funcs->load_cursor_image_check) @@ -333,16 +348,19 @@ xf86_hide_cursors(ScrnInfoPtr scrn) } } -static void +static Bool xf86_crtc_show_cursor(xf86CrtcPtr crtc) { -if (!crtc->cursor_shown && crtc->cursor_in_range) { -crtc->funcs->show_cursor(crtc); -crtc->cursor_shown = TRUE; -} +if (!crtc->cursor_in_range) +return TRUE; + +if (!crtc->cursor_shown) +crtc->cursor_shown = xf86_driver_show_cursor(crtc); + +return crtc->cursor_shown; } -void +Bool xf86_show_cursors(ScrnInfoPtr scrn) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); @@ -352,9 +370,11 @@ xf86_show_cursors(ScrnInfoPtr scrn) for (c = 0; c < xf86_config->num_crtc; c++) { xf86CrtcPtr crtc = xf86_config->crtc[c]; -if (crtc->enabled) -xf86_crtc_show_cursor(crtc); +if (crtc->enabled && !xf86_crtc_show_cursor(crtc)) +return FALSE; } + +return TRUE; } static void @@ -653,7 +673,7 @@ xf86_cursors_init(ScreenPtr screen, int max_width, int max_height, int flags) cursor_info->SetCursorPosition = xf86_set_cursor_position; cursor_info->LoadCursorImageCheck = xf86_load_cursor_image; cursor_info->HideCursor = xf86_hide_cursors; -cursor_info->ShowCursor = xf86_show_cursors; +cursor_info->ShowCursorCheck = xf86_show_cursors; cursor_info->UseHWCursor = xf86_use_hw_cursor; if (flags & HARDWARE_CURSOR_ARGB) { cursor_info->UseHWCursorARGB = xf86_use_hw_cursor_argb; diff --git a/hw/xfree86/ramdac/xf86Cursor.h b/hw/xfree86/ramdac/xf86Cursor.h index 320ec0c..11a03b6 100644 --- a/hw/xfree86/ramdac/xf86Cursor.h +++ b/hw/xfree86/ramdac/xf86Cursor.h @@ -16,6 +16,7 @@ typedef struct _xf86CursorInfoRec { Bool (*LoadCursorImageCheck) (ScrnInfoPtr pScrn, unsigned c
[PATCH xserver 2/3] modesetting: Immediately handle failure to set HW cursor, v5
Based on v4 by Alexandre Courbot 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. Signed-off-by: Michael Thayer --- hw/xfree86/drivers/modesetting/drmmode_display.c | 15 +-- hw/xfree86/drivers/modesetting/drmmode_display.h | 1 - 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 61a0e27..8e68c0e 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -813,13 +813,8 @@ drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image) for (i = 0; i < ms->cursor_width * ms->cursor_height; i++) ptr[i] = image[i]; // cpu_to_le32(image[i]); -if (drmmode_crtc->cursor_up || !drmmode_crtc->first_cursor_load_done) { -Bool ret = drmmode_set_cursor(crtc); -if (!drmmode_crtc->cursor_up) -drmmode_hide_cursor(crtc); -drmmode_crtc->first_cursor_load_done = TRUE; -return ret; -} +if (drmmode_crtc->cursor_up) +return drmmode_set_cursor(crtc); return TRUE; } @@ -835,12 +830,12 @@ drmmode_hide_cursor(xf86CrtcPtr crtc) ms->cursor_width, ms->cursor_height); } -static void +static Bool drmmode_show_cursor(xf86CrtcPtr crtc) { drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private; drmmode_crtc->cursor_up = TRUE; -drmmode_set_cursor(crtc); +return drmmode_set_cursor(crtc); } static void @@ -1108,7 +1103,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = { .set_mode_major = drmmode_set_mode_major, .set_cursor_colors = drmmode_set_cursor_colors, .set_cursor_position = drmmode_set_cursor_position, -.show_cursor = drmmode_show_cursor, +.show_cursor_check = drmmode_show_cursor, .hide_cursor = drmmode_hide_cursor, .load_cursor_argb_check = drmmode_load_cursor_argb_check, diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index 50976b8..3b0eb2b 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -93,7 +93,6 @@ typedef struct { struct dumb_bo *cursor_bo; Bool cursor_up; Bool set_cursor2_failed; -Bool first_cursor_load_done; uint16_t lut_r[256], lut_g[256], lut_b[256]; drmmode_bo rotate_bo; -- 2.9.3 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver 3/3] modesetting: allow switching from software to hardware cursors (v5).
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 Signed-off-by: Michael Thayer --- hw/xfree86/drivers/modesetting/drmmode_display.c | 30 ++-- hw/xfree86/drivers/modesetting/drmmode_display.h | 1 - 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c index 8e68c0e..bbe1a5f 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.c +++ b/hw/xfree86/drivers/modesetting/drmmode_display.c @@ -756,37 +756,33 @@ drmmode_set_cursor(xf86CrtcPtr crtc) drmmode_ptr drmmode = drmmode_crtc->drmmode; uint32_t handle = drmmode_crtc->cursor_bo->handle; modesettingPtr ms = modesettingPTR(crtc->scrn); +CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen); int ret = -EINVAL; -if (!drmmode_crtc->set_cursor2_failed) { -CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen); - -ret = -drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, - handle, ms->cursor_width, ms->cursor_height, - cursor->bits->xhot, cursor->bits->yhot); -if (!ret) -return TRUE; - -/* -EINVAL can mean that an old kernel supports drmModeSetCursor but - * not drmModeSetCursor2, though it can mean other things too. */ -if (ret == -EINVAL) -drmmode_crtc->set_cursor2_failed = TRUE; -} +ret = drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, +handle, ms->cursor_width, ms->cursor_height, +cursor->bits->xhot, cursor->bits->yhot); +/* -EINVAL can mean that an old kernel supports drmModeSetCursor but + * not drmModeSetCursor2, though it can mean other things too. */ if (ret == -EINVAL) ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, ms->cursor_width, ms->cursor_height); -if (ret) { +/* -ENXIO normally means that the current drm driver supports neither + * cursor_set nor cursor_set2. Disable hardware cursor support for + * the rest of the session in that case. */ +if (ret == -ENXIO) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn); xf86CursorInfoPtr cursor_info = xf86_config->cursor_info; cursor_info->MaxWidth = cursor_info->MaxHeight = 0; drmmode_crtc->drmmode->sw_cursor = TRUE; +} + +if (ret) /* fallback to swcursor */ return FALSE; -} return TRUE; } diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h index 3b0eb2b..f774250 100644 --- a/hw/xfree86/drivers/modesetting/drmmode_display.h +++ b/hw/xfree86/drivers/modesetting/drmmode_display.h @@ -92,7 +92,6 @@ typedef struct { int dpms_mode; struct dumb_bo *cursor_bo; Bool cursor_up; -Bool set_cursor2_failed; uint16_t lut_r[256], lut_g[256], lut_b[256]; drmmode_bo rotate_bo; -- 2.9.3 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH xserver] glamor: Accelerate XYBitmap PutImage
Adam Jackson writes: > This could probably be made faster if GL exposed an R1 texture format. The existing core text code emulates R1 textures; it seems like you could use those programs for this. We could also use that for PushPixels at some point. -- -keith signature.asc Description: PGP signature ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver 1/3] glamor: Accelerate PutImage for XYBitmap format
Upload the bitmap and use a program like TE Text program to draw it, avoiding fallbacks for this case. Signed-off-by: Keith Packard --- glamor/glamor_image.c | 183 +++--- glamor/glamor_priv.h | 3 + 2 files changed, 176 insertions(+), 10 deletions(-) diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c index 3158749..798277b 100644 --- a/glamor/glamor_image.c +++ b/glamor/glamor_image.c @@ -29,8 +29,8 @@ */ static Bool -glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, -int w, int h, int leftPad, int format, char *bits) +glamor_put_image_zpixmap_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, +int w, int h, char *bits) { ScreenPtr screen = drawable->pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); @@ -52,12 +52,6 @@ glamor_put_image_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, if (!glamor_pm_is_solid(gc->depth, gc->planemask)) goto bail; -if (format == XYPixmap && drawable->depth == 1 && leftPad == 0) -format = ZPixmap; - -if (format != ZPixmap) -goto bail; - x += drawable->x; y += drawable->y; box.x1 = x; @@ -84,6 +78,165 @@ bail: return FALSE; } +static const char vs_vars_put_bitmap[] = +"attribute vec4 primitive;\n" +"attribute vec2 source;\n" +"varying vec2 image_pos;\n"; + +static const char vs_exec_put_bitmap[] = +" vec2 pos = primitive.zw * vec2(gl_VertexID&1, (gl_VertexID&2)>>1);\n" +GLAMOR_POS(gl_Position, (primitive.xy + pos)) +" image_pos = source + pos;\n"; + +static const char fs_vars_put_bitmap[] = +"varying vec2 image_pos;\n"; + +static Bool +glamor_put_bitmap_use(PixmapPtr pixmap, GCPtr gc, glamor_program *prog, void *arg) +{ +if (!glamor_set_solid(pixmap, gc, TRUE, prog->fg_uniform)) +return FALSE; +glamor_set_color(pixmap, gc->bgPixel, prog->bg_uniform); +return TRUE; +} + +static const char fs_exec_put_bitmap[] = +" ivec2 itile_texture = ivec2(image_pos);\n" +" uint x = uint(itile_texture.x & 7);\n" +" itile_texture.x >>= 3;\n" +" uint texel = texelFetch(font, itile_texture, 0).x;\n" +" uint bit = (texel >> x) & uint(1);\n" +" if (bit == uint(0))\n" +" gl_FragColor = bg;\n" +" else\n" +" gl_FragColor = fg;\n"; + +const glamor_facet glamor_facet_put_bitmap = { +.name = "put_bitmap", +.version = 130, +.vs_vars = vs_vars_put_bitmap, +.vs_exec = vs_exec_put_bitmap, +.fs_vars = fs_vars_put_bitmap, +.fs_exec = fs_exec_put_bitmap, +.locations = glamor_program_location_fg | glamor_program_location_bg | glamor_program_location_font, +.source_name = "source", +.use = glamor_put_bitmap_use, +}; + +/* + * Use a program like the terminal emulator text program to fetch single + * bits from the source image and expand them to full pixel values. + */ +static Bool +glamor_put_image_xybitmap_gl(DrawablePtr drawable, GCPtr gc, int x, int y, + int w, int h, int leftPad, char *bits) +{ +ScreenPtr screen = drawable->pScreen; +glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); +PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); +glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); +uint32_t byte_stride = BitmapBytePad(w + leftPad); +GLuint texture_id; +glamor_program *prog; +char *vbo_offset; +GLshort *v; +int box_index; +int off_x, off_y; +Bool ret = FALSE; + +if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) +return FALSE; + +glamor_make_current(glamor_priv); + +prog = &glamor_priv->put_bitmap_prog; + +if (prog->failed) +goto bail; + +if (!prog->prog) { +if (!glamor_build_program(screen, prog, &glamor_facet_put_bitmap, NULL, NULL, NULL)) +goto bail; +} + +if (!glamor_use_program(pixmap, gc, prog, NULL)) +goto bail; + +glGenTextures(1, &texture_id); +glActiveTexture(GL_TEXTURE1); +glBindTexture(GL_TEXTURE_2D, texture_id); + +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); +glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + +glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +glamor_priv->suppress_gl_out_of_memory_logging = true; +glTexImage2D(GL_TEXTURE_2D, 0, GL_R8UI, byte_stride, h, + 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, bits); +glamor_priv->suppress_gl_out_of_memory_logging = false; +if (glGetError() == GL_OUT_OF_MEMORY) +goto bail; + +glUniform1i(prog->font_uniform, 1); + +/* Set up the vertex buffers for the font and destination */ + +v = glamor_get_vbo_space(drawable->pScreen, (6 * sizeof (GLshort)), &vbo_offset); + +glEnableVertexAttribArray(
[PATCH xserver 0/3] glamor: Accelerate XY format images
I took Adam's code to speed up XY format bitmaps and generalized that for XY format pixmaps too; that speeds up small pixmaps by a bunch. Then I went and wrote some much faster XY bitmap code which expands the image with the GPU (just like core text). That turns out to be faster for large images, but slower for small images due to GL overhead. On my Haswell laptop running Xephyr with -glamor-skip-present: 1: xy_old 2: xy_new 1 2 Operation - - 10900.099900.0 ( 9.165) PutImage XY 10x10 square 1740.0 2160.0 ( 1.241) PutImage XY 100x100 square 83.2 90.4 ( 1.087) PutImage XY 500x500 square 11800.0 351000.0 (29.746) PutImage XYBitmap 10x10 square 6280.081600.0 (12.994) PutImage XYBitmap 100x100 square 752.014300.0 (19.016) PutImage XYBitmap 500x500 square I'd like to know why the GPU expansion version has so much GL overhead; it "should" be faster for everything as it uploads a lot less data to the GPU. I'd also like to try writing an XYPixmap that did all of the plane merging in the fragment shader. That "should" be faster for large images than merging on the CPU. I tried just using my XYBitmap code in a loop with a rasterop, but that's actually slower than using the CPU (at least on my machine). Presumably doing 24 texture uploads isn't all that fast? ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver 2/3] glamor: Accelerate up XY pixmap putimage a little
Convert the image to a temporary CPU pixmap, then copy that to the destination. This is a lot faster for small images, and not any slower for large images. Signed-off-by: Keith Packard --- glamor/glamor_image.c | 48 1 file changed, 48 insertions(+) diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c index 798277b..47968e2 100644 --- a/glamor/glamor_image.c +++ b/glamor/glamor_image.c @@ -237,6 +237,52 @@ bail: return ret; } +/* + * Create a temporary in-memory pixmap, put the image there then copy + * to the destination. + */ + +static Bool +glamor_put_image_xy_gl(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, + int w, int h, int leftPad, int format, char *bits) +{ +PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); +glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); +ScreenPtr screen = drawable->pScreen; +PixmapPtr temp_pixmap = NULL; +DrawablePtr temp_drawable; +GCPtr temp_gc; +Boolret = FALSE; +ChangeGCVal gcv[3]; + +if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) +return FALSE; + +temp_pixmap = (*screen->CreatePixmap)(screen, w, h, drawable->depth, GLAMOR_CREATE_PIXMAP_CPU); +if (!temp_pixmap) +goto bail; +temp_drawable = &temp_pixmap->drawable; +temp_gc = GetScratchGC(temp_drawable->depth, screen); +if (!temp_gc) +goto bail_pixmap; + +/* copy mode for the first plane to clear all of the other bits */ +gcv[0].val = GXcopy; +gcv[1].val = gc->fgPixel; +gcv[2].val = gc->bgPixel; +ChangeGC(NullClient, temp_gc, GCFunction|GCForeground|GCBackground, gcv); +ValidateGC(temp_drawable, temp_gc); +(*temp_gc->ops->PutImage)(temp_drawable, temp_gc, depth, 0, 0, w, h, leftPad, format, bits); +(*gc->ops->CopyArea)(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y); +ret = TRUE; + +FreeScratchGC(temp_gc); +bail_pixmap: +(*screen->DestroyPixmap)(temp_pixmap); +bail: +return ret; +} + static void glamor_put_image_bail(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int leftPad, int format, char *bits) @@ -256,6 +302,8 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, return; break; case XYPixmap: +if (glamor_put_image_xy_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits)) +return; break; case XYBitmap: if (glamor_put_image_xybitmap_gl(drawable, gc, x, y, w, h, leftPad, bits)) -- 2.9.3 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver 3/3] glamor: Switch XY bitmap putimage function for small images
Use the glamor_put_image_xy_gl for small images as that is quite a bit faster. Signed-off-by: Keith Packard --- glamor/glamor_image.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/glamor/glamor_image.c b/glamor/glamor_image.c index 47968e2..6a70e6a 100644 --- a/glamor/glamor_image.c +++ b/glamor/glamor_image.c @@ -306,8 +306,13 @@ glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, return; break; case XYBitmap: -if (glamor_put_image_xybitmap_gl(drawable, gc, x, y, w, h, leftPad, bits)) -return; +if (w * h >= 100 * 100) { +if (glamor_put_image_xybitmap_gl(drawable, gc, x, y, w, h, leftPad, bits)) +return; +} else { +if (glamor_put_image_xy_gl(drawable, gc, depth, x, y, w, h, leftPad, format, bits)) +return; +} break; } glamor_put_image_bail(drawable, gc, depth, x, y, w, h, leftPad, format, bits); -- 2.9.3 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel