Re: VK_EXT_aquire_xlib_display and kernel security concerns
On 10/16/2017 05:49 PM, Keith Packard wrote: Andy Ritgerwrites: If the NVIDIA X driver finds an HMD display, it: (a) Marks it as disconnected. (b) Does not make its EDID available to RandR clients. So, unless I'm mistaken, RandR clients will see the HMD as an RandR output. But, perhaps the problem is that the RandR client cannot tell that the output is an HMD, since the EDID is not available? It will look like a regular disconnected output... Item (b) was only an artifact of how the code is structured, not an intentional decision. To be fair, disconnected output with EDID sounds like a slightly odd state. Well, the goal is to have regular X clients ignore the output, for which reporting a Disconnected state seems the best way. The only question is then how to report to 'special' clients that there is an HMD present on the connector. We could: a) Create a new request to query 'hidden' outputs b) Report the 'connected' state in a new output property c) Let the client infer that a valid EDID indicates that a display is connected. We would still send RROutputChangeNotify events when the device was connected/disconnected so that applications could track the state of the device, but of course the 'connection' status in that event would always be Disconnected. Anyway, we can update the NVIDIA driver behavior to match whatever consensus we reach here. Let's try to poke holes in the simple plan that Dave suggested above; I can't see any offhand, but I haven't tried to implement it in the X server or applications either. Btw, was there any particular reason the acquire_xlib_display extension used Xlib types instead of xcb types? That's just what was asked for IIRC. There could be a VK_EXT_acquire_xcb_display, VK_EXT_acquire_wayland_display, VK_EXT_acquire_win32_display, etc. as demand dictates. Thanks, -James ___ 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: VK_EXT_aquire_xlib_display and kernel security concerns
On 10/16/2017 01:33 PM, Dave Airlie wrote: On 17 October 2017 at 06:01, James Jones <jajo...@nvidia.com> wrote: On 10/16/2017 12:28 PM, Keith Packard wrote: James Jones <jajo...@nvidia.com> writes: I think at a lower level, we have different views of how vkGetPhysicalDeviceDisplayPropertiesKHR/VK_KHR_display works. vkGetPhysicalDeviceDisplayPropertiesKHR() is suppose to enumerate all the displays on a given device. In many devices, the display controller and rendering hardware are separate devices, so it's up to user space to figure out the connection between them, and user DMAbufs to pass rendered output to the display. Understood. In that case, no displays should be enumerated on the "rendering hardware" device in Vulkan, unless the driver vendor opts for heroics. I assumed DRM drivers would try the display-capable node, then fall back to a render node if that failed. No, they cannot as the display node is protected from normal user access. Right, but normal processes don't need the display node, or aren't supposed to. I assumed apps that need direct-to-display would have elevated permissions on systems configured to require it, or use "acquire" extensions, potentially combined with native secondary auth mechanisms, to get access. This is why it bothers me that "normal user access" doesn't include display enumeration. If they use acquire extensions they get display enumeration, the problem is display enumeration before the acquire would need special permission elevation. VK_KHR_display, but the core of it is really just a display enumeration API. Right, I think all I really need is to hand the driver a connection to the X server and it can use that to enumerate the available displays through the Vulkan API. The thing is if you are running under X I don't think apps should be bypassing things and going straight to hw enumeration, it makes too many problems harder, and in systems where all you have are separated display/render devices it makes this extension impossible to implement, since as you've said vulkan has no way to enumerate such things. Given the current definition of a Vulkan-capable device, yes. It's annoying that Vulkan can't yet expose a device that only has displays and the ability to import memory objects and create images from them. I prefer the enumeration ability as a general principle though. Is the discussion with Daniel Vetter captured somewhere so I can read up on the objections? I couldn't find it with a naive Google or DRI devel search. Since we have to actually publish our kernel APIs people find inventive ways to do things with them that we don't end up breaking later, and having to find ways to keep their stupid working. You don't have this problem, nobody opens /dev/nvidia directly from an app and does anything useful, and even if they do you guys don't care. Previously for example we opened up DRM_WAIT_VBLANK or forgot to close it, this leds to apps directly poking it behind the X server back, trying to determine timings outside the compositor incorrectly. So if we expose all the enumeration APIs to "render" only nodes, then we will get information leaks, like the currently attached framebuffer for planes, ways to poll state like device connectedness, (we get people trying to bypass dpms all the time), able to pull the device properties out, it's just a genie in a bottle scenario once we provide it we can't repeal it later. It's only sane that we restrict the API to what we want to support. Thanks for the background Dave. This is a good point. If the granularity of current ioctls makes it difficult to draw the right line, would proposing new ioctls that can only query non-sensitive state (TBD what that is) be the right direction? I don't think EXT_acquire_xlib_display is the right use case to justify such enumeration, as I like the proposed solution of enumerating through X11 in this case. However, I think direct enumeration is generally useful functionality, if nothing else just for things like vkinfo or DRM equivalents. Thanks, -James Dave. ___ 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: VK_EXT_aquire_xlib_display and kernel security concerns
On 10/16/2017 12:28 PM, Keith Packard wrote: James Jones <jajo...@nvidia.com> writes: I think at a lower level, we have different views of how vkGetPhysicalDeviceDisplayPropertiesKHR/VK_KHR_display works. vkGetPhysicalDeviceDisplayPropertiesKHR() is suppose to enumerate all the displays on a given device. In many devices, the display controller and rendering hardware are separate devices, so it's up to user space to figure out the connection between them, and user DMAbufs to pass rendered output to the display. Understood. In that case, no displays should be enumerated on the "rendering hardware" device in Vulkan, unless the driver vendor opts for heroics. I assumed DRM drivers would try the display-capable node, then fall back to a render node if that failed. No, they cannot as the display node is protected from normal user access. Right, but normal processes don't need the display node, or aren't supposed to. I assumed apps that need direct-to-display would have elevated permissions on systems configured to require it, or use "acquire" extensions, potentially combined with native secondary auth mechanisms, to get access. This is why it bothers me that "normal user access" doesn't include display enumeration. Everyone focuses on the direct-to-display swapchain portion of VK_KHR_display, but the core of it is really just a display enumeration API. Right, I think all I really need is to hand the driver a connection to the X server and it can use that to enumerate the available displays through the Vulkan API. For (c), I hope that after reading the above, there is no such assumption. Of course the app can't acquire such a display, but that shouldn't be unexpected. I had hoped that there would be a way to enumerate "hidden" HMD displays using XRandR, and I thought you provided that in your XRandR changes. Yes, we're figuring out how to do that now. Dave has posted proposed kernel patches to the list which adds an EDID-based quirk to mark HMD displays as 'special'. Our current thought is that we would list the 'special' outputs as Disconnected, but provide an EDID property for them. That way, normal X applications would continue to ignore them, but a special application could still discover the target device using EDID information. Cool. It seems to be suggested below as well. If apps have that, they can use vkGetRandROutputDisplayEXT to map them to VkDisplayKHR objects, rather than the other way around. That way, they could avoid an attempt to acquire a display from the wrong X server. Yes, I have a test application which works this way. However, as the nVidia driver is hiding HMD outputs from X applications, an application wanting to support both nVidia and DRM drivers will have to try both methods. Once a method is finalized to expose HMDs without having desktops pick them up, we can probably switch to that behavior. We'll have to review the proposed disconnected-but-has-EDID idea above. Currently, we have an option to force exposure of HMDs, but then they just look like normal displays to userspace. FWIW, I think this would be great. I don't see why enumeration should be a privileged operation. chmod +x the display directory please :-) That was my initial plan, and it obviously works fine. Daniel Vetter has a reasonable aversion to providing this kind of access; "bad things" have happened in the past when we expose system information of this kind to all applications. Besides, this fails in the case where the display device and rendering device are separate, so we end up needing another path for that anyways. Given the current definition of a Vulkan-capable device, yes. It's annoying that Vulkan can't yet expose a device that only has displays and the ability to import memory objects and create images from them. I prefer the enumeration ability as a general principle though. Is the discussion with Daniel Vetter captured somewhere so I can read up on the objections? I couldn't find it with a naive Google or DRI devel search. Let me know if you have suggestions to improve the Vulkan APIs. Would it be reasonable to add a new function to the acquire_xlib_display extension that would let you pass the Display into the API before the vkGetPhysicalDeviceDisplayPropertiesKHR call? That would offer the least impact on applications using the API, allowing them to have a single enumeration mechanism for both DRM and nVidia devices. Right now, the pattern looks like: open X connection enumerate displays using vk APIs select desired display acquire xlib display That would change to open X connection tell vk about the X connection enumerate displays using vk APIs select desired display acquire xlib display We've very much tried to avoid giving Vulkan itself stateful knowledge of a window system. Swap
Re: VK_EXT_aquire_xlib_display and kernel security concerns
On 10/14/2017 02:00 AM, "Keith Packard" wrote: I've implemented this extension in DRM and have run into a conflict between the spec and the Linux architecture. The VkDisplayKHR parameter for VK_EXT_acquire_xlib_display can be found in two different ways: 1) Enumerate displays using vkGetPhysicalDeviceDisplayPropertiesKHR 2) Enumerate RROutputs using xcb_randr_get_screen_resources and convert that to a VkDisplayKHR with vkGetRandROutputDisplayEXT The former makes some assumptions which are not valid in all environments: a) It assumes that the Vulkan rendering driver can touch all of the display resources on the system. Under DRM, a regular user running vulkan can only open a 'rendering' node, which denies it all access to the display resources associated with the rendering hardware. b) It assumes that the rendering driver knows about the display hardware. There are many modern systems where the display hardware and rendering hardware are entirely separate, and we must use DMAbufs to get the rendered output sent from the rendering driver to the display driver. c) It assumes that X controls all display resources on the system. If you're running more than one X server on different displays, then you can end up with a VkDisplayKHR object which the X server doesn't manage, and hence cannot be 'acquired'. I think at a lower level, we have different views of how vkGetPhysicalDeviceDisplayPropertiesKHR/VK_KHR_display works. vkGetPhysicalDeviceDisplayPropertiesKHR() is suppose to enumerate all the displays on a given device. Vulkan is agnostic to the underlying device model, so whether you want to init it on a DRM render or full (control? I forget the terminology now.) device is up to the driver. I assumed DRM drivers would try the display-capable node, then fall back to a render node if that failed. Regardless, it is supposed to enumerate all displays, whether you can control them and perform modesets on them, acquire them, or none of those ops. Enumeration in itself can be useful for purposes of correlation, which would allow apps to discover where their windows are without native window system APIs if some future extensions materialize. Everyone focuses on the direct-to-display swapchain portion of VK_KHR_display, but the core of it is really just a display enumeration API. Therefore, for (b), such a device would enumerate no displays. It would be up to the app to do some kind of cross-device interop to get images from its render-only device to its display-only device. Hence all the allocator work and stuff. If the driver/hardware vendor chooses to hide that detail when presenting to X/wayland/etc, great, but it's pretty hard to hide when doing direct-to-display presentation, as you point out. Vulkan's an explicit API, and I never expected drivers to hide this detail for direct-to-display swapchains. For (c), I hope that after reading the above, there is no such assumption. Of course the app can't acquire such a display, but that shouldn't be unexpected. I had hoped that there would be a way to enumerate "hidden" HMD displays using XRandR, and I thought you provided that in your XRandR changes. It seems to be suggested below as well. If apps have that, they can use vkGetRandROutputDisplayEXT to map them to VkDisplayKHR objects, rather than the other way around. That way, they could avoid an attempt to acquire a display from the wrong X server. Going the other way, from Vulkan display enumeration -> X grab, was sort of intended to be a stop-gap until RandR caught up. However, it works fine as well if you don't mind a try-and-fail enumeration model. I just try to avoid that when possible. I can work around a) by opening up access rights to view display resources to all applications with access to render nodes. I've had push back on this plan from the DRM maintainers as it dramatically changes the access control model used by DRM with unknown consequences for both security and application abuse. FWIW, I think this would be great. I don't see why enumeration should be a privileged operation. chmod +x the display directory please :-) I can't work around b) and c) as the vkGetPhysicalDeviceDisplayPropertiesKHR function doesn't have any information about the window system to allow it to limit the set of display resources to those shared by X and Vulkan. Using method 2) provides the necessary control as vkGetRandROutputDisplayEXT gets both the Vulkan and X contexts and can make suitable choices about what it can support. However, the reason vkAcquireXlibDisplay takes a VkDisplayKHR object instead of an RROutput parameter is so that it can access displays which X may not want to advertise to all clients. I don't think that's necessary; we can advertise the RROutput, but just not tell clients that it is "Connected" when the display shouldn't be incorporated into a
Re: [PATCH 0/5] GLX updates
For the series, Reviewed-by: James Jones jajo...@nvidia.com Thanks, -James On 06/02/2015 10:41 AM, Adam Jackson wrote: This series stubs in the server side of support for some newer GLX extensions. They won't do much without corresponding Mesa updates, but are necessary for such updates to work. - ajax ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH] Add -iglx +iglx to Xserver.man
On 11/25/2014 11:37 PM, Robert Morell wrote: On Tue, Nov 25, 2014 at 11:20:58PM -0800, Alan Coopersmith wrote: On 11/25/14 10:36 PM, Robert Morell wrote: On Tue, Nov 25, 2014 at 07:26:14PM -0800, Alan Coopersmith wrote: Covers the current state after commits 99f0365b1fbdfd9238b9f, d0da0e9c3bb8fe0cd4879, e3aa13b8d63ea2fba6eb4 were all applied. Signed-off-by: Alan Coopersmith alan.coopersm...@oracle.com --- man/Xserver.man | 10 ++ 1 file changed, 10 insertions(+) diff --git a/man/Xserver.man b/man/Xserver.man index c03830c..69ff626 100644 --- a/man/Xserver.man +++ b/man/Xserver.man @@ -181,6 +181,16 @@ prints a usage message. .B \-I causes all remaining command line arguments to be ignored. .TP 8 +.B \-iglx +Prohibit creating indirect GLX contexts. Indirect GLX is of limited use, +since it only supports up to OpenGL 1.4; it's slower than direct contexts; Technically, there exists protocol for much if not all of OpenGL 2.1, and some extensions beyond that. But not all server and client implementations support it... Sorry, I copied that from the comments in the commit that actually created the options, and took Eric's word for it: http://cgit.freedesktop.org/xorg/xserver/commit/?id=99f0365b1fbdfd9238b9f5cc28491e4e6c7324f1 Would only fully supports up to OpenGL 1.4, with partial support for OpenGL 2.1 and some later extensions be more accurate? Or is there a better wording someone can think of? I'm not really sure myself what the extent of official Khronos-sanctioned protocol support is -- it's spread out over a bunch of extensions, and if there is any overall unifying documentation I'm not aware of it. Maybe a more future-proof statement appropriate for the man page would be something like lacks support for many modern OpenGL features and extensions? If you want to be specific, there is enough GLX protocol approved to implement OpenGL 2.0. Some of the stuff in 2.1 (PBO, mostly) is indefinitely awaiting a reviewer at Khronos. If any Khronos members are interested in reviewing that, let me know. However, I agree a slightly vaguer comment is probably the way to go for the man page. Thanks, -James +and it opens a large attack surface for protocol parsing errors. +This is the default unless +iglx is specified, though it may not be honored +by GLX implementations other than the one provided with the X server. For what it's worth, in case anyone finds this thread in the archives, I'll point out that NVIDIA's implementation does honor this option in newer drivers, which contain the following entry in the changelog: * Implemented support for disabling indirect GLX context creation using the -iglx option available on X.Org server release 1.16 and newer. Note that future X.Org server releases may make the -iglx option the default. To re-enable support for indirect GLX on such servers, use the +iglx option. That's good - perhaps we can drop that qualification if both NVIDIA AMD will be supporting the check in their Xorg 1.17 ABI compatible versions. I was thinking of older driver versions when I'd written it, but obviously, due to ABI changes, there shouldn't be many (any?) GLX implementations that can both be loaded by Xorg 1.17 and do not support this flag, so I don't know why I was thinking of that. Yeah, good point. - Robert But your text above is still accurate, so other than perhaps softening the OpenGL 1.4 limitation, Reviewed-by: Robert Morell rmor...@nvidia.com +.TP 8 +.B +iglx +Allow creating indirect GLX contexts. +.TP 8 .B \-maxbigreqsize \fIsize\fP sets the maximum big request to .I size -- 1.7.9.2 -- -Alan Coopersmith- alan.coopersm...@oracle.com Oracle Solaris Engineering - http://blogs.oracle.com/alanc ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH v2] Add -iglx +iglx to Xserver.man
On 11/26/2014 01:01 PM, Alan Coopersmith wrote: Covers the current state after commits 99f0365b1fbdfd9238b9f, d0da0e9c3bb8fe0cd4879, e3aa13b8d63ea2fba6eb4 were all applied. Signed-off-by: Alan Coopersmith alan.coopersm...@oracle.com --- v2: Made claims about what Indirect GLX supports more vague yet more accurate than before, at the suggestion of Robert James. Also dropped note about compatibility with third-party GLX modules, since they should add support as part of their 1.17 ABI updates. man/Xserver.man | 10 ++ 1 file changed, 10 insertions(+) diff --git a/man/Xserver.man b/man/Xserver.man index c03830c..3bf844f 100644 --- a/man/Xserver.man +++ b/man/Xserver.man @@ -181,6 +181,16 @@ prints a usage message. .B \-I causes all remaining command line arguments to be ignored. .TP 8 +.B \-iglx +Prohibit creating indirect GLX contexts. Indirect GLX is of limited use, +since it lacks support for many modern OpenGL features and extensions; +it's slower than direct contexts; and it opens a large attack surface for +protocol parsing errors. +This is the default unless +iglx is specified. +.TP 8 +.B +iglx +Allow creating indirect GLX contexts. +.TP 8 .B \-maxbigreqsize \fIsize\fP sets the maximum big request to .I size Reviewed-by: James Jones jajo...@nvidia.com ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Present proto feedback
Hi Keith, Thanks for incorporating all the suggested fencing in the present protocol. I think the latest version looks good, and just had some minor feedback: -I just noticed the email you listed for me in the Acknowledgements was incorrect. It should be jajones 'at' nvidia.com. -Should there be a UST version of PresentNotifyMSC as well? I guess I'm unclear what this request is for. Is it to implement things like glXWaitVideoSyncSGI? Thanks, -James ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: Present extension name alternatives
On 08/13/2013 02:25 PM, Bryce W. Harrington wrote: On Tue, Aug 13, 2013 at 02:02:59PM -0700, Alan Coopersmith wrote: On 08/13/13 01:09 PM, Keith Packard wrote: Present is a noun and a verb (with different pronunciations, no less). As such, it makes a pretty miserable extension name. Can you remind me what it actually does? I see several posts on your blog describing various features, but didn't see a big picture/introduction for those who haven't been closely following DRI3000 development. It basically provides a streamlined path for getting pixels from the DRI pixmap created by DRI3, to an X drawable that can be processed by the compositing manager. If I've understood keith's blog posts properly... Essentially, it is an in-X way to solve the redirected direct rendering problem that Wayland/et al would solve. Fwiw, if I had a vote I'd say stick with Present, not worth bikeshedding on. Agreed. Naming stuff is hard. Often the first thing that comes to mind is as good as anything else. Present seems better than any of the synonyms at least. There's precedent for using the term present for these operations that graphics programmers shouldn't get confused. As another option: EGL uses the term Post to describe surface presentation operations. PASTE is a pretty cool acronym, but is probably more misleading than any of the other suggestions :-) Thanks, -James ('mete' does have a nice archaic ring though...) Bryce ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel --- This email message is for the sole use of the intended recipient(s) and may contain confidential information. Any unauthorized review, use, disclosure or distribution is prohibited. If you are not the intended recipient, please contact the sender by reply email and destroy all copies of the original message. --- ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: Current DRI3 specification
On 06/08/2013 11:18 AM, Daniel Stone wrote: Hi, On 7 June 2013 13:30, James Jones jajo...@nvidia.com wrote: We do need more than the 'make it pretty' requirement above though. What you describe is what interactive rendering apps want, when you're translating some sort of input into graphics with as little latency as possible. Video/streaming apps would rather queue up several frames as close to the HW presentation mechanism as possible to avoid hiccups, but have precise control over when the frames present so they can still do A/V sync right with the longer queues. That's where the OML-type stuff with counters and timers becomes interesting. Those are the two important scenarios I know of right now. I can't say for certain others don't exist. This is only true to the extent that the entire pipeline is totally predictable in terms of latency; That doesn't sound right to me. I would think you want what I described above in high-latency or fluctuating latency situations, where you want to accurately do something a few hundred milliseconds in the future, rather than inaccurately do something ASAP. The synchronization is supposed to happen at the end of the pipeline, where more accuracy is possible. given that isn't even remotely true with these kinds of system, timing feedback, to allow clients to adjust accordingly, is more important. GStreamer, for example, has really detailed code to feed back in frame timestamps and use the actual, rather than predicted, presentation time to adjust its clock. Yes, if your system doesn't allow accurate semi-high latency presentation, that's what you'd want. This idea is for a system that does allow accurate presentation after a series of maybe-not-so-predictable-latency operations though. I think ideally, you have both: A framework that allows reliable latency when the HW/driver supports it, AND accurate feedback to handle the situations where the driver or hardware can't provide sufficiently reliable presentation. I'm certainly not opposed to feedback mechanisms. This isn't theoretical either. We have robust implementations of the high latency/accurate mechanism in VDPAU and GL_NV_present_video: ftp://download.nvidia.com/XFree86/vdpau/doxygen/html/group___vdp_presentation_queue.html http://www.opengl.org/registry/specs/NV/present_video.txt The general list of fences mechanism is theoretical at the moment, but is the logical next step in generalizing both the high latency/reliable and low-latency/best effort mechanisms IMHO. Over the past few years, it's proven interesting to have mechanisms to synchronize graphics processing at the front and end of the graphics pipeline (GL fences, EGL fences, X fence syncs to a lesser extent). Having a similarly powerful way to express synchronization at the beginning of the display pipeline seems like it could be a useful tool as well. Thanks, -James Cheers, Daniel ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: Current DRI3 specification
On 06/07/2013 10:10 AM, Keith Packard wrote: * PGP Signed by an unknown key James Jones jajo...@nvidia.com writes: Yeah, I think the semantics are compatible. We allocate these buffers on the server-side, but I don't think that affects the interaction with Present. DRI2 allocates them server-side as well for GLX compliance, but with the way Intel hardware does MSAA, it's just not feasible to allow for multi-process rendering to the same buffers so I've given up any pretense. I've never been fond of the OML triplet because the values don't correspond well to the counters/clocks our HW has. Yeah, I haven't found anyone who likes the OML stuff, but it's the spec we have... However, it was always the intent that there would be a bunch of external-event triggered types of fences added via other extensions (trigger at a given timer value, when a certain scanline is reached, triggered while in the vblank region or a certain bracketed set of scanlines, etc.) I'm not sure how general I want to try and make this. As far as I can understand it, applications want to display no faster than frame rate, and tear if they go over time on a frame. Just getting to that will probably be complicated enough without adding the ability to sync to other mechanisms. Perhaps rather than merge these into sync or present, there could be small, separate extensions that introduce various new ways to create a fence sync object with these properties. I think Fence objects are completely unrelated to the display system -- Fence objects provide a way to serialize GPU access to the underlying render buffers. Trying to stir those up into more general counters that provide precise times when buffers get displayed seems confusing to me. Fences are just abstract boolean barriers that can be used to synchronize graphics with other stuff. I don't see them as inherently a part or excluded from any particular sub-system. Having them as simple Sync counters might make sense, the chief trouble there is that OML links the three values together, and Sync doesn't support that notion. One such extension could introduce the OML values either as a combined fence object, or as 3 separate objects. I had imagined the present operation would take an arbitrary length ordered list of fence sync objects to wait for, which would be passed down to drivers where they could be collapsed when possible. For example, if the HW or kernel driver supports waiting for the first vblank after a given timer value was reached as a single operation, the fence sequence { TIMER, VBLANK } could be collapsed into a single HW/kernel wait operation by the corresponding X driver. Do you actually need this, or would it just be 'cool'? I don't have anyone asking for anything like this, just the simple 'make it pretty' requirement described above. We don't need it to be this general. I'd just like to solve present synchronization once and for all, and this seems like a logical way to do so. The interface and the naive implementation don't seem that much more complex than what you have already IMHO. We do need more than the 'make it pretty' requirement above though. What you describe is what interactive rendering apps want, when you're translating some sort of input into graphics with as little latency as possible. Video/streaming apps would rather queue up several frames as close to the HW presentation mechanism as possible to avoid hiccups, but have precise control over when the frames present so they can still do A/V sync right with the longer queues. That's where the OML-type stuff with counters and timers becomes interesting. Those are the two important scenarios I know of right now. I can't say for certain others don't exist. Thanks, -James ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: Current DRI3 specification
On 06/05/2013 06:20 PM, Keith Packard wrote: * PGP Signed by an unknown key James Jones jajo...@nvidia.com writes: I read through this and the extension specification below. The DRI3 stuff doesn't directly affect our driver at the moment of course, but I like the direction it's going and the proposed/implied interactions between DRI3 and Present. Thanks much for the review. I think the most relevant question for the binary nVidia driver is whether you think you can do something similar in terms of mapping your back buffers into X pixmaps for use by Present. Yeah, I think the semantics are compatible. We allocate these buffers on the server-side, but I don't think that affects the interaction with Present. Oh, I'm curious if you think we should be mapping the OML_sync_control UST/MSC/SBC triplet into Sync extension counters. It sure seems like a natural fit to me, and would reduce the size of the Present extension quite a bit. I've never been fond of the OML triplet because the values don't correspond well to the counters/clocks our HW has. However, it was always the intent that there would be a bunch of external-event triggered types of fences added via other extensions (trigger at a given timer value, when a certain scanline is reached, triggered while in the vblank region or a certain bracketed set of scanlines, etc.) Perhaps rather than merge these into sync or present, there could be small, separate extensions that introduce various new ways to create a fence sync object with these properties. One such extension could introduce the OML values either as a combined fence object, or as 3 separate objects. I had imagined the present operation would take an arbitrary length ordered list of fence sync objects to wait for, which would be passed down to drivers where they could be collapsed when possible. For example, if the HW or kernel driver supports waiting for the first vblank after a given timer value was reached as a single operation, the fence sequence { TIMER, VBLANK } could be collapsed into a single HW/kernel wait operation by the corresponding X driver. Thanks, -James I read through your futex-based fence sync implementation notes as well. Seems reasonable to me. I didn't try too hard to poke holes in it though. I've had a couple of other positive reviews of that code; obviously it's going to take some actual failures before people figure out why it doesn't work right :-) ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: Current DRI3 specification
On 06/04/2013 04:51 PM, Keith Packard wrote: * PGP Signed by an unknown key I've gotten DRI3 working and posted an article about it here: http://keithp.com/blogs/dri3_extension/ I read through this and the extension specification below. The DRI3 stuff doesn't directly affect our driver at the moment of course, but I like the direction it's going and the proposed/implied interactions between DRI3 and Present. Hopefully this will provide a path in X11/Mesa for the Nouveau guys to get rid of the implicit kernel-based serialization if they choose to tackle that task. I read through your futex-based fence sync implementation notes as well. Seems reasonable to me. I didn't try too hard to poke holes in it though. Thanks, -James I thought now might be a great time to post the current DRI3 protocol specification and let people take a look (and comment!) The DRI3 Extension Version 1.0 2013-6-4 Keith Packard kei...@keithp.com Intel Corporation 1. Introduction The DRI3 extension provides mechanisms to translate between direct rendered buffers and X pixmaps. When combined with the Present extension, a complete direct rendering solution for OpenGL is provided. The direct rendered buffers are passed across the protocol via standard POSIX file descriptor passing mechanisms. On Linux, these buffers are DMA-BUF objects. DRI3 also includes a mechanism to translate between Linux Futexes and X Sync extension Fences. This provides a synchronization mechanism which can be used to serialize access to shared render buffers. 1.1. Acknowledgments Eric Anholt e...@anholt.net Dave Airlie airl...@redhat.com Kristian Høgsberg k...@bitplanet.net James Jones jano...@nvidia.com ❄ ❄ ❄ ❄ ❄ ❄ ❄ 2. Data Types DRI3EVENTID { XID } Defines a unique event delivery target for DRI3 events. Multiple event IDs can be allocated to provide multiple distinct event delivery contexts. DRI3EVENTMASK { DRI3ConfigureNotifyMask } The DRI3 extension also uses the RandR extension Provider data type to select among multiple GPUs on a single screen and the Sync extension fence object to provide graphics object synchronization. ❄ ❄ ❄ ❄ ❄ ❄ ❄ 4. Errors No errors are defined by the DRI3 extension. ❄ ❄ ❄ ❄ ❄ ❄ ❄ 5. Events DRI3 adds a ConfigureNotify event to inform clients about window configuration changes which can affect the allocation of window-related direct rendered buffers. ❄ ❄ ❄ ❄ ❄ ❄ ❄ 6. Protocol Types DRI3DRIVER { DRI3DriverDRI DRI3DriverVDPAU } These values describe the type of driver the client will want to load. The server sends back the name of the driver to use for the screen in question. ❄ ❄ ❄ ❄ ❄ ❄ ❄ 7. Extension Initialization The name of this extension is DRI3 ┌─── DRI3QueryVersion client-major-version: CARD32 client-minor-version: CARD32 ▶ major-version: CARD32 minor-version: CARD32 └─── The client sends the highest supported version to the server and the server sends the highest version it supports, but no higher than the requested version. Major versions changes can introduce incompatibilities in existing functionality, minor version changes introduce only backward compatible changes. It is the clients responsibility to ensure that the server supports a version which is compatible with its expectations. Backwards compatible changes included addition of new requests. ❄ ❄ ❄ ❄ ❄ ❄ ❄ 8. Extension Requests ┌─── DRI3Open drawable: DRAWABLE driverType: DRI3DRIVER provider: PROVIDER ▶ nfd: CARD8 driver: STRING device: FD └─── Errors: Drawable, Value, Match This requests that the X server open the direct rendering device associated with drawable, driverType and RandR provider. The provider must support SourceOutput or SourceOffload. The direct rendering library used to implement the specified 'driverType' is returned in 'driver'. The file descriptor for the device is returned in 'device'. 'nfd' will be set to one (this is strictly a convenience for XCB which otherwise would need request-specific information about how many file descriptors were associated with this reply). ┌─── DRI3PixmapFromBuffer pixmap: PIXMAP drawable: DRAWABLE size: CARD32 width, height, stride: CARD16 depth, bpp: CARD8
Re: Initial DRI3000 protocol specs available
On 03/21/2013 03:41 PM, Keith Packard wrote: * PGP Signed by an unknown key James Jones jajo...@nvidia.com writes: If you associate an X Fence Sync with your swap operation, the driver has the option to trigger it directly from the client command stream and wake up only the applications waiting for that fence. The compositor, if using GL, could have received the swap notification event and already programmed the response compositing based on it before the swap even completes, and just insert a token to make the GPU or kernel wait for the fence to complete before executing the compositing rendering commands. Sorry for the long lag; I've been thinking about this quite a bit. Sorry for the lag in my response as well. I went and read through your earlier proposal as well as reading through the related GL fence extensions and I think this is what we want in general terms. There are two distinct times of interest here: 1) When the buffer is free and can be used for another frame. 2) When the buffer contents are visible on the screen. (This needs some weasel wording so that the system can do things like severely limit background applications or invisible applications.) Providing X Fence Sync objects for each of these times seems like it will give applications what they need. The second issue is that we must relate these X Fence Sync objects to direct rendering so that clients using shared objects outside of the X protocol can synchronize their operations with the X server. For that, I think we can share a page between application and X server that contains all of the necessary fence information along with a pthreads semaphore object that can lock access to the fence and also provide a way to block until the X Fence Sync object is signaled. There's some work going on to get something very much like fence sync objects into the Linux kernel as well, I think starting with something from the Android kernel trees, and with input from some people working on fence objects usable to synchronize access to dmabuf objects. It might make sense to use these primitives rather than shared memory+pthreads to share the syncs between direct rendering clients and the X server. At the very least, it would be nice to have an abstraction where the implementation details of the sync objects weren't directly exposed by the API. This eliminates the explicit Swap events and replaces them with Sync objects. I'll write this up in the extension description and try to get some code written in the next couple of weeks. I like the sound of the overall direction. Looking forward to what you come up with. Thanks, -James ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: Initial DRI3000 protocol specs available
On 03/07/2013 05:17 PM, Keith Packard wrote: * PGP Signed by an unknown key James Jones jajo...@nvidia.com writes: There didn't seem to be much interest outside of NVIDIA, so besides fence sync, the ideas are tabled internally ATM. This shouldn't surprise you though -- no-one else needs this kind of synchronization, so it's really hard for anyone to evaluate it. And, DRI2 offers 'sufficient' support for the various GL sync extensions. I was referring to the multi-buffer/tear-free presentation part, not the synchronization parts. I still rather surprised everyone thinks implicit synchronization is a good idea though. I don't think we're the only ones that have loosely defined command buffer processing in HW anymore. Meh. So, what I'd like to know is if you think nVidia could take advantage of the Swap extension so that nVidia 3D applications could do the whole Swap redirect plan? If so, then I'm a lot more interested in figuring out how we can get apps using the necessary fencing to actually make it work right. Sorry, I've been ignoring this thread because of the DRI3000 title, so I missed the point where it defined a generic swap mechanism in X protocol. From my reading, applications do roughly this in the spec: Pixmap pix[N] = MakeListOfPixmaps(N) Window win = MakeWindow(); int n = 0; while (1) { // Stuff here to ensure pix[n] is idle. Render(pix[n]); SwapRegion(win, pix[n]); } I think I saw in one branch of the thread that you might allow redirecting the swap request out to a composite manager rather than processing in X. Basically that's what I proposed (and Aaron presented some of at XDC) a few years ago and got no feedback. However, my full proposal included: -setting the list of pixmaps associated with a window up front, so that the composite manager or GL applications could query them and do work once to bind them in to GL. This is pretty expensive. With your proposal, this could probably be done lazily and tracked in a cache-type thing, but if applications wanted to be dumb and generate a new pixmap for every frame, nothing is stopping them. Applications would do something like: Pixmap pix[N] XCreateWindowPixmaps(win, N, pix /* out */); up front, and composite managers would get an event notifying them that win now has those N pixmaps associated with it. Swaps would be done by indexing into that array rather than sending the actual pixmap ID. -Using sync object lists in place of all the hard-coded timing information. We've never been a fan of the OML style swap timing semantics. It doesn't line up well with our HW. Why not allow arbitrary fence objects to dictate when the swapping occurs? Then apps that just want a simple vsync can just send a vsync fence. Apps that want exact timing can query what types of counters are available and get exact timing on different HW that supports different timers. -I had a bunch of GLX proposals to solve that mess. -Redirecting present operations (or swaps) to the composite manager was central to the proposal. It looks like a lot of the details and psuedo-code didn't make it in the final public presentation, just a high-level overview. I'll see if I can dig up more of that. Here's the URL to the presentation. Just skip all the fence sync parts. http://people.freedesktop.org/~aplattner/x-presentation-and-synchronization.pdf Thanks, -James ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: Initial DRI3000 protocol specs available
On 03/07/2013 12:49 PM, Keith Packard wrote: * PGP Signed by an unknown key Aaron Plattner aplatt...@nvidia.com writes: If I'm understanding this correctly, this requires the X server to receive a notification from the GPU that the swap is complete so it can send the SwapComplete event. Is there any chance this could be done with a Fence instead? The application could specify the fence in the Swap request, and then use that fence to block further rendering on the GPU or wait on the fence from the CPU. From what I've heard from application developers, there are two different operations here: 1) Throttle application rendering to avoid racing ahead of the screen 2) Keeping the screen up-to-date with simple application changes, but not any faster than frame rate. The SwapComplete event is designed for this second operation. Imagine a terminal emulator; it doesn't want to draw any faster than frame rate, but any particular frame can be drawn in essentially zero time. This application doesn't want to *block* at all, it wants to keep processing external events, like getting terminal output and user input events. As I understand it, a HW fence would cause the terminal emulator to stall down in the driver, blocking processing of all of the events and terminal output. If you associate an X Fence Sync with your swap operation, the driver has the option to trigger it directly from the client command stream and wake up only the applications waiting for that fence. The compositor, if using GL, could have received the swap notification event and already programmed the response compositing based on it before the swap even completes, and just insert a token to make the GPU or kernel wait for the fence to complete before executing the compositing rendering commands. Thanks, -James For simple application throttling, that wouldn't use these SwapComplete events, rather it would use whatever existing mechanisms exist for blocking rendering to limit the application frame rate. We typically try to do the scheduling on the GPU when possible because triggering an interrupt and waking up the X server burns power and adds latency for no good reason. Right, we definitely don't want a high-performance application to block waiting for an X event to arrive before it starts preparing the next frame. ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: Initial DRI3000 protocol specs available
On 03/07/2013 01:19 PM, Owen Taylor wrote: On Thu, 2013-02-28 at 16:55 -0800, Keith Packard wrote: * It would be great if we could figure out a plan to get to the point where the exact same application code is going to work for proprietary and open source drivers. When you get down to the details of swap this isn't close to the case currently. Agreed -- the problem here is that except for the nVidia closed drivers, everything else implicitly serializes device access through the kernel, providing a natural way to provide some defined order of operations. Failing that, I'd love to know what mechanisms *could* work with that design. Fence syncs. Note the original fence sync + multi-buffer proposal solved basically the same problems you're trying to solve here, as well as everything Owen's WM spec updates do, but more generally, and with that, a little more implementation complexity. It included proposals to make minor updates to GLX/EGL as well to tie them in with the newer model. There didn't seem to be much interest outside of NVIDIA, so besides fence sync, the ideas are tabled internally ATM. I don't think serialization is actually the big issue - although it's annoying to deal with fences that are no-op for the open sources, it's pretty well defined where you have to insert them, and because they are no-op's for the open source drivers, there's little overhead. Notification is more of an issue. - Because swap handled client side in some drivers, INTEL_swap_event is seen as awkward to implement. I'm not sure what could be done here, other than to have some way for the X server to get information about the swap and stuff it into the event stream, of course. It could be as simple as having the client stuff the event data to the X server itself. It may be that a focus on redirection makes things easier - once the compositor is involved, we can't get away from X server involvement. The compositor is the main case where the X server can be completely bypassed when swapping. And I'm less concerned about API divergence for the compositor. (Not that I *invite* it...) - There is divergence on some basic behaviors, e.g., whether glXSwapBuffers() glFinish() waits for the swap to complete or not. glXSwapBuffers is pretty darn explicit in saying that it *does not* wait for the swap to complete, and glFinish only promises to synchronize the effects of rendering (contents of the frame buffer), not the actual swap operation itself. I'm not sure how we're supposed to respond when drivers ignore the spec and do their own thing? I wish the GLX specification was clear enough so we actually knew who was ignoring the spec and doing their own thing... ;-) The GLX specification describes the swap operation as the contents of the back buffer become the contents of the front buffer ... that seems like an operation on the contents of the frame buffer. The GLX spec is plenty clear here. It states: Subsequent OpenGL commands can be issued immediately, but will not be executed until the buffer swapping has completed... And glFinish, besides the fact that it counts as a GL command, isn't defined as simply waiting until effects on the framebuffer land. All rendering, client, and server (GL server, not X server) state side effects from previous operations must settle before it returns. SwapBuffers affects all three of those. Same for fence syncs with condition GL_SYNC_GPU_COMMANDS_COMPLETE. So if the drawable swapped is current to the thread calling swap buffers, and they issue any other GL commands afterwards, including glFinish, glFenceSync, etc., those commands can't complete until after the swap operation does. For glFinish, that means it can't return. For fence, the fence won't trigger until the swap finishes. If implementations aren't behaving that way, it's a bug in the implementation. Not to say our implementation doesn't have bugs, but AFAIK, we don't have that one. Thanks, -James But getting into the details here is a bit of a distraction - my goal is to try to get us to convergence so we have only one API with well defined behaviors. - When rendering with a compositor, the X server is innocent of relevant information about timing and when the application should draw additional new frames. I've been working on handing this via client = compositor protocols With 'Swap', I think the X server should be involved as it is necessary to get be able to 'idle' buffers which aren't in use after the compositor is done with them. I tried to outline a sketch of how that would work before. (https://mail.gnome.org/archives/wm-spec-list/2013-January/msg0.html) But this adds a lot of complexity to the minimal client, especially when a client wants to work both redirected and unredirected. Right, which is why I think fixing the X server to help here would be better. If the goal is really to obsolete the proposed WM
Re: [PATCH v2 9/9] Xext: Add per-device SyncCounters
On 3/20/12 12:04 AM, Peter Hutterer wrote: On Fri, Mar 16, 2012 at 06:15:30PM -0700, James Jones wrote: Below: +SyncCounter* +SyncInitDeviceIdleTime(DeviceIntPtr dev) +{ +char timer_name[64]; +sprintf(timer_name, DEVICEIDLETIME %d, dev-id); + +return init_system_idle_counter(timer_name, dev-id); +} + +void SyncRemoveDeviceIdleTime(SyncCounter *counter) +{ +/* ResetProc frees the list before devices are shutdown and try to + * delete their counters again */ Is this comment true? I didn't see code to do so in 1/9. Did you forget to add it there, or forget to clean up this comment? Or is it just too late in Friday for me to be reading code correctly :-) not 100% correct anymore, but the condition is still needed. Now the problem is FreeAllResources() frees all system counters before the devices are shut down, check if there are any left before freeing the device's counter I'll change the comment to the above. Cheers, Peter Ah, OK, thanks. Given that change, Reviewed-by: James Jones jajo...@nvidia.com For the series. -James +if (!xorg_list_is_empty(SysCounterList)) +xorg_list_del(counter-pSysCounterInfo-entry); +} + diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 27b533c..84c7aee 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -139,4 +139,7 @@ extern void SyncDestroySystemCounter( ); extern void SyncExtensionInit(void); + +extern SyncCounter *SyncInitDeviceIdleTime(DeviceIntPtr dev); +extern void SyncRemoveDeviceIdleTime(SyncCounter *counter); #endif /* _SYNCSRV_H_ */ diff --git a/dix/devices.c b/dix/devices.c index 7478ad6..a488d41 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -87,6 +87,7 @@ SOFTWARE. #include enterleave.h /* for EnterWindow() */ #include xserver-properties.h #include xichangehierarchy.h /* For XISendDeviceHierarchyEvent */ +#include syncsrv.h /** @file * This file handles input device-related stuff. @@ -419,9 +420,13 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) RecalculateMasterButtons(dev); +/* initialise an idle timer for this device*/ +dev-idle_counter = SyncInitDeviceIdleTime(dev); + return TRUE; } + /** * Switch a device off through the driver and push it onto the off_devices * list. A device will not send events while disabled. All clients are @@ -447,6 +452,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) if (*prev != dev) return FALSE; +SyncRemoveDeviceIdleTime(dev-idle_counter); +dev-idle_counter = NULL; + /* float attached devices */ if (IsMaster(dev)) { diff --git a/include/inputstr.h b/include/inputstr.h index 86db811..7517b8e 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -606,6 +606,8 @@ typedef struct _DeviceIntRec { /* XTest related master device id */ int xtest_master_id; + +struct _SyncCounter *idle_counter; } DeviceIntRec; typedef struct { nvpublic ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: [PATCH v2 9/9] Xext: Add per-device SyncCounters
Below: On 3/14/12 9:10 PM, Peter Hutterer wrote: Previously, we only had one idle alarm that was triggered for all devices, whenever the user used any device, came back from suspend, etc. Add system SyncCounters for each device (named DEVICEIDLETIME x, with x being the device id) that trigger on that device only. This allows for enabling/disabling devices based on interaction with other devices. Popular use-case: disable the touchpad when the keyboard just above the touchpad stops being idle. Signed-off-by: Peter Huttererpeter.hutte...@who-t.net Reviewed-by: Jeremy Huddlestonjerem...@apple.com --- Changes to v1: - adapt to SysCounterGetPrivate - adapt to SysCounterList being a linked list Xext/sync.c| 48 +++- Xext/syncsrv.h |3 +++ dix/devices.c |8 include/inputstr.h |2 ++ 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 5479381..c2f6573 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -70,6 +70,7 @@ PERFORMANCE OF THIS SOFTWARE. #include syncsrv.h #include syncsdk.h #include protocol-versions.h +#include inputstr.h #includestdio.h #if !defined(WIN32) @@ -2715,12 +2716,22 @@ SyncInitServerTime(void) typedef struct { XSyncValue *value_less; XSyncValue *value_greater; +int deviceid; } IdleCounterPriv; static void IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return) { -CARD32 idle = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds; +int deviceid; +CARD32 idle; + +if (pCounter) { +SyncCounter *counter = pCounter; +IdleCounterPriv *priv = SysCounterGetPrivate(counter); +deviceid = priv-deviceid; +} else +deviceid = XIAllDevices; +idle = GetTimeInMillis() - lastDeviceEventTime[deviceid].milliseconds; XSyncIntsToValue (pValue_return, idle, 0); } @@ -2813,7 +2824,7 @@ IdleTimeWakeupHandler (pointer pCounter, int rc, pointer LastSelectMask) if (!less !greater) return; -IdleTimeQueryValue (NULL,idle); +IdleTimeQueryValue (pCounter,idle); if ((greater XSyncValueGreaterOrEqual (idle, *greater)) || (less XSyncValueLessOrEqual (idle, *less))) @@ -2849,8 +2860,8 @@ IdleTimeBracketValues (pointer pCounter, CARD64 *pbracket_less, priv-value_less= pbracket_less; } -static void -SyncInitIdleTime (void) +static SyncCounter* +init_system_idle_counter(const char *name, int deviceid) { CARD64 resolution; XSyncValue idle; @@ -2860,12 +2871,39 @@ SyncInitIdleTime (void) IdleTimeQueryValue (NULL,idle); XSyncIntToValue (resolution, 4); -idle_time_counter = SyncCreateSystemCounter(IDLETIME, idle, resolution, +idle_time_counter = SyncCreateSystemCounter(name, idle, resolution, XSyncCounterUnrestricted, IdleTimeQueryValue, IdleTimeBracketValues); +priv-deviceid = deviceid; priv-value_less = priv-value_greater = NULL; idle_time_counter-pSysCounterInfo-private = priv; + +return idle_time_counter; +} + +static void +SyncInitIdleTime (void) +{ +init_system_idle_counter(IDLETIME, XIAllDevices); } + +SyncCounter* +SyncInitDeviceIdleTime(DeviceIntPtr dev) +{ +char timer_name[64]; +sprintf(timer_name, DEVICEIDLETIME %d, dev-id); + +return init_system_idle_counter(timer_name, dev-id); +} + +void SyncRemoveDeviceIdleTime(SyncCounter *counter) +{ +/* ResetProc frees the list before devices are shutdown and try to + * delete their counters again */ Is this comment true? I didn't see code to do so in 1/9. Did you forget to add it there, or forget to clean up this comment? Or is it just too late in Friday for me to be reading code correctly :-) Thanks, -James +if (!xorg_list_is_empty(SysCounterList)) +xorg_list_del(counter-pSysCounterInfo-entry); +} + diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 27b533c..84c7aee 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -139,4 +139,7 @@ extern void SyncDestroySystemCounter( ); extern void SyncExtensionInit(void); + +extern SyncCounter *SyncInitDeviceIdleTime(DeviceIntPtr dev); +extern void SyncRemoveDeviceIdleTime(SyncCounter *counter); #endif /* _SYNCSRV_H_ */ diff --git a/dix/devices.c b/dix/devices.c index 7478ad6..a488d41 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -87,6 +87,7 @@ SOFTWARE. #include enterleave.h /* for EnterWindow() */ #include xserver-properties.h #include xichangehierarchy.h /* For XISendDeviceHierarchyEvent */ +#include syncsrv.h /** @file * This file handles input device-related stuff. @@ -419,9 +420,13 @@ EnableDevice(DeviceIntPtr dev, BOOL
Re: [PATCH 0/9] per-device idle counters
On 3/14/12 5:20 PM, Peter Hutterer wrote: On Wed, Mar 14, 2012 at 05:11:04PM -0700, James Jones wrote: I like the cleanups here. I prefer the SysCounterGetPrivate() helper over the macro, but don't particularly think the need to allow SyncNumSystemCounters to go negative by decrementing in ResetProc() is a win for clarity. sorry, I'm having troubles parsing this sentence. So you'd prefer leaving SyncNumSystemCounters out decrement it automatically even after the container array has been removed already? or force-reset it to 0 and only decrement while the list is still present, leaving the counter at 0? (which is what the first diff below adds) Sorry for not being clear. I would prefer not force-resetting it to 0, aka, leaving 1/9 out of the series. You could check SyncCounterList != NULL instead of SyncNumSystemCounters in the 9/9. If the inconsistency needs to be fixed, I slightly prefer Jamey's linked-list patch. The inconsistency between the list and count would even be useful if there was somewhere to assert/BUG_WARN that the number settles to 0. I suppose you could add a BUG_WARN_MSG(SystemCounterList || (SyncNumSystemCounters == 0)) in SyncCreateSystemCounter() to catch it on server generations. Thanks, -James Cheers, Peter On 3/14/12 4:30 PM, Peter Hutterer wrote: On Wed, Mar 14, 2012 at 09:01:13AM -0700, Jamey Sharp wrote: This series seems like a good idea to me! I have a few review comments though: Patch 1 seems strange. Shouldn't the counters themselves get freed at reset? If they are, shouldn't that lead to the number of counters reaching 0? you're right but the order is a tad weird. The ResetProc is called before the counters are cleaned up, so we free the container list but the number is still correct. Later, the number goes down to 0 when the counters are actually freed. Technically correct, but weird. I think the diff below would make sense to merge into patch 1/9. This way, we remove all knowledge of system counters in the ResetProc and don't get any weird effects. diff --git a/Xext/sync.c b/Xext/sync.c index 6c8c564..bf47c93 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -1200,8 +1200,8 @@ FreeCounter(void *env, XID id) SysCounterList[i] = SysCounterList[i+1]; } } +SyncNumSystemCounters--; } - SyncNumSystemCounters--; } free(pCounter); return Success; I guess the input ABI should get bumped for the patch that stores per-device idle times. We decided to bump ABI more aggressively, right? correct, but I need to go through my lists to check whether I've got anything else that bumps the ABI in the near future. If so, I prefer bundling them with one ABI bump. I haven't checked: is it possible to build xserver without SYNC, or to disable it at runtime? If so, the final patch needs some conditionals, I assume. in configure.ac:1312, it's always defined, so no conditionals are necessary. AC_DEFINE(XSYNC, 1, [Support XSync extension]) Here's a request you can ignore if you like: Please consider making SYSCOUNTERPRIV a static inline instead of a macro, and removing the cast from inside it. That'd be different from the usual idiom in the X server, but the usual idiom is dumb. :-) I'd prefer to see all the callers assign their pointer pCounters to an appropriately-typed local once right at the beginning of the function, which also serves as documentation for what type you're supposed to pass in there. How does this one look then? I'd squash this in but it's easier to review as a diff on top. From cc02b58e95822a50658ef7fe13e862c3f569ee22 Mon Sep 17 00:00:00 2001 From: Peter Huttererpeter.hutte...@who-t.net Date: Thu, 15 Mar 2012 09:27:24 +1000 Subject: [PATCH] Xext: replace the macro with a static inline function. Signed-off-by: Peter Huttererpeter.hutte...@who-t.net --- Xext/sync.c| 24 ++-- Xext/syncsrv.h |2 -- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 6c8c564..5f74dab 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -115,6 +115,15 @@ static void SyncInitServerTime(void); static void SyncInitIdleTime(void); +static inline void* +SysCounterGetPrivate(SyncCounter *counter) +{ +BUG_WARN(!IsSystemCounter(counter)); + +return counter-pSysCounterInfo ? counter-pSysCounterInfo-private : NULL; +} + + static Bool SyncCheckWarnIsCounter(const SyncObject* pSync, const char *warning) { @@ -2747,7 +2756,8 @@ IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return) CARD32 idle; if (pCounter) { -IdleCounterPriv *priv = SYSCOUNTERPRIV(pCounter); +SyncCounter *counter = pCounter; +IdleCounterPriv *priv = SysCounterGetPrivate(counter); deviceid = priv-deviceid; } else deviceid = XIAllDevices
Re: [PATCH 0/9] per-device idle counters
I like the cleanups here. I prefer the SysCounterGetPrivate() helper over the macro, but don't particularly think the need to allow SyncNumSystemCounters to go negative by decrementing in ResetProc() is a win for clarity. Thanks, -James On 3/14/12 4:30 PM, Peter Hutterer wrote: On Wed, Mar 14, 2012 at 09:01:13AM -0700, Jamey Sharp wrote: This series seems like a good idea to me! I have a few review comments though: Patch 1 seems strange. Shouldn't the counters themselves get freed at reset? If they are, shouldn't that lead to the number of counters reaching 0? you're right but the order is a tad weird. The ResetProc is called before the counters are cleaned up, so we free the container list but the number is still correct. Later, the number goes down to 0 when the counters are actually freed. Technically correct, but weird. I think the diff below would make sense to merge into patch 1/9. This way, we remove all knowledge of system counters in the ResetProc and don't get any weird effects. diff --git a/Xext/sync.c b/Xext/sync.c index 6c8c564..bf47c93 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -1200,8 +1200,8 @@ FreeCounter(void *env, XID id) SysCounterList[i] = SysCounterList[i+1]; } } +SyncNumSystemCounters--; } - SyncNumSystemCounters--; } free(pCounter); return Success; I guess the input ABI should get bumped for the patch that stores per-device idle times. We decided to bump ABI more aggressively, right? correct, but I need to go through my lists to check whether I've got anything else that bumps the ABI in the near future. If so, I prefer bundling them with one ABI bump. I haven't checked: is it possible to build xserver without SYNC, or to disable it at runtime? If so, the final patch needs some conditionals, I assume. in configure.ac:1312, it's always defined, so no conditionals are necessary. AC_DEFINE(XSYNC, 1, [Support XSync extension]) Here's a request you can ignore if you like: Please consider making SYSCOUNTERPRIV a static inline instead of a macro, and removing the cast from inside it. That'd be different from the usual idiom in the X server, but the usual idiom is dumb. :-) I'd prefer to see all the callers assign their pointer pCounters to an appropriately-typed local once right at the beginning of the function, which also serves as documentation for what type you're supposed to pass in there. How does this one look then? I'd squash this in but it's easier to review as a diff on top. From cc02b58e95822a50658ef7fe13e862c3f569ee22 Mon Sep 17 00:00:00 2001 From: Peter Huttererpeter.hutte...@who-t.net Date: Thu, 15 Mar 2012 09:27:24 +1000 Subject: [PATCH] Xext: replace the macro with a static inline function. Signed-off-by: Peter Huttererpeter.hutte...@who-t.net --- Xext/sync.c| 24 ++-- Xext/syncsrv.h |2 -- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 6c8c564..5f74dab 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -115,6 +115,15 @@ static void SyncInitServerTime(void); static void SyncInitIdleTime(void); +static inline void* +SysCounterGetPrivate(SyncCounter *counter) +{ +BUG_WARN(!IsSystemCounter(counter)); + +return counter-pSysCounterInfo ? counter-pSysCounterInfo-private : NULL; +} + + static Bool SyncCheckWarnIsCounter(const SyncObject* pSync, const char *warning) { @@ -2747,7 +2756,8 @@ IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return) CARD32 idle; if (pCounter) { -IdleCounterPriv *priv = SYSCOUNTERPRIV(pCounter); +SyncCounter *counter = pCounter; +IdleCounterPriv *priv = SysCounterGetPrivate(counter); deviceid = priv-deviceid; } else deviceid = XIAllDevices; @@ -2758,8 +2768,8 @@ IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return) static void IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMask) { -IdleCounterPriv *priv = SYSCOUNTERPRIV(pCounter); SyncCounter *counter = pCounter; +IdleCounterPriv *priv = SysCounterGetPrivate(counter); XSyncValue *less = priv-value_less, *greater = priv-value_greater; XSyncValue idle, old_idle; @@ -2835,7 +2845,8 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa static void IdleTimeWakeupHandler (pointer pCounter, int rc, pointer LastSelectMask) { -IdleCounterPriv *priv = SYSCOUNTERPRIV(pCounter); +SyncCounter *counter = pCounter; +IdleCounterPriv *priv = SysCounterGetPrivate(counter); XSyncValue *less = priv-value_less, *greater = priv-value_greater; XSyncValue idle; @@ -2856,7 +2867,8 @@ static void IdleTimeBracketValues (pointer pCounter, CARD64 *pbracket_less,
Re: [PATCH] Don't free font closures prematurely (#31501)
This patch isn't a correct fix. It just avoids the crash. I wish I could remember why. There was some discussion about this on IRC between Adam Jackson and I a long time ago that basically concluded the correct fix is really hard. If anyone keeps really old IRC logs around (around 8 or 9 months back), that would have made a good update in the bug report. Sorry I didn't follow up. Thanks, -James nvpublic On 7/29/11 11:23 AM, Jeremy Huddleston jerem...@freedesktop.org wrote: This patch is attached to https://bugs.freedesktop.org/show_bug.cgi?id=31501 , but so far nobody has bothered to send it to xorg-devel ... I have not tested it and am just forwarding it along for comment since it reportedly addresses this crasher. From 59616dde4a04d407db76d55b06bcc82d646f42cd Mon Sep 17 00:00:00 2001 From: James Jones jajo...@nvidia.com Date: Thu, 9 Dec 2010 16:14:05 -0800 Subject: [PATCH] Don't free font closures prematurely (#31501) X-NVConfidentiality: public When doing Xinerama, font ops are dispatched across backend screens. To avoid sleeping a client more than once in these cases, logic was added to avoid sleeping and destroy the closure structure when the client is already asleep. However, the operation isn't always completed when this cleanup is performed. To freeing prematurely, only free the closure data if the operation is finished, or if the operation never slept. The latter catches the xinerama case. Signed-off-by: James Jones jajo...@nvidia.com --- dix/dixfonts.c | 102 +++ include/closestr.h |5 +++ 2 files changed, 75 insertions(+), 32 deletions(-) diff --git a/dix/dixfonts.c b/dix/dixfonts.c index ccb4627..c0ae28b 100644 --- a/dix/dixfonts.c +++ b/dix/dixfonts.c @@ -239,6 +239,8 @@ doOpenFont(ClientPtr client, OFclosurePtr c) *newname; int newlen; intaliascount = 20; +BoolfromDispatch = c-from_dispatch; +Boolfinished = FALSE; /* * Decide at runtime what FontFormat to use. */ @@ -270,6 +272,8 @@ doOpenFont(ClientPtr client, OFclosurePtr c) BitmapFormatScanlineUnit8; +c-from_dispatch = FALSE; + if (client-clientGone) { if (c-current_fpe c-num_fpes) @@ -374,13 +378,16 @@ bail: c-fontid, FontToXError(err)); } ClientWakeup(c-client); +finished = TRUE; xinerama_sleep: -for (i = 0; i c-num_fpes; i++) { -FreeFPE(c-fpe_list[i]); +if (finished || fromDispatch) { +for (i = 0; i c-num_fpes; i++) { +FreeFPE(c-fpe_list[i]); +} +free(c-fpe_list); +free(c-fontname); +free(c); } -free(c-fpe_list); -free(c-fontname); -free(c); return TRUE; } @@ -461,6 +468,7 @@ OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontna c-num_fpes = num_fpes; c-fnamelen = lenfname; c-flags = flags; +c-from_dispatch = TRUE; c-non_cachable_font = cached; (void) doOpenFont(client, c); @@ -592,6 +600,10 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c) char*bufptr; char*bufferStart; intaliascount = 0; +BoolfromDispatch = c-from_dispatch; +Boolfinished = FALSE; + +c-from_dispatch = FALSE; if (client-clientGone) { @@ -667,7 +679,7 @@ doListFontsAndAliases(ClientPtr client, LFclosurePtr c) ((pointer) c-client, fpe, name, namelen, tmpname, resolvedlen, c-current.private); if (err == Suspended) { -if (ClientIsAsleep(client)) +if (!ClientIsAsleep(client)) ClientSleep(client, (ClientSleepProcPtr)doListFontsAndAliases, c); @@ -822,13 +834,16 @@ finish: bail: ClientWakeup(client); +finished = TRUE; xinerama_sleep: -for (i = 0; i c-num_fpes; i++) -FreeFPE(c-fpe_list[i]); -free(c-fpe_list); -free(c-savedName); -FreeFontNames(names); -free(c); +if (finished || fromDispatch) { +for (i = 0; i c-num_fpes; i++) +FreeFPE(c-fpe_list[i]); +free(c-fpe_list); +free(c-savedName); +FreeFontNames(names); +free(c); +} free(resolved); return TRUE; } @@ -880,6 +895,7 @@ ListFonts(ClientPtr client, unsigned char *pattern, unsigned length, c-current.list_started = FALSE; c-current.private = 0; c-haveSaved = FALSE; +c-from_dispatch = TRUE; c-savedName = 0; doListFontsAndAliases(client, c); return Success; @@ -891,6 +907,8 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) FontPathElementPtr fpe; int err = Successful; char *name; +BoolfromDispatch = c-from_dispatch; +Boolfinished = FALSE; int namelen; int numFonts; FontInfoRec fontInfo, @@ -902,6 +920,8 @@ doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) intaliascount = 0
Re: Are we ready to tag release libXext 1.3.0?
Thanks for digging that patch up, but it is incomplete. Let me plug in the missing functions and do a little testing, then I'll post an updated patch. Thanks, -James nvpublic On 5/7/11 9:40 PM, Alan Coopersmith alan.coopersm...@oracle.com wrote: Thanks - as you probably saw I pushed libXext 1.3.0, but the equivalent changes for xcb don't seem to be in the git master repo yet - is this: https://github.com/cubanismo/xcbproto/commit/6c022bc1fe34316f80f4c3817bc69a70099c6320 the needed change? Did it get lost in review somewhere? (Sorry, I haven't kept track, and just trying to get everything finished up for integrating the client side of Sync 3.1 to our packages to go along with the Xorg 1.10 integration.) -Alan Coopersmith-alan.coopersm...@oracle.com Oracle Solaris Platform Engineering: X Window System On 05/ 5/11 08:09 PM, James Jones wrote: I'm not aware of any fence sync issues that would hold up a release. Everything should be ready to go. Thanks, -James nvpublic On 5/5/11 7:09 PM, Alan Coopersmith alan.coopersm...@oracle.com wrote: It looks like we've still not done a release of libXext with the new XSyncAwaitFence() API yet, even though the proto server were released a while ago - is there anything remaining to do there or any reason not to go ahead and make a libXext 1.3.0 release? -- -Alan Coopersmith-alan.coopersm...@oracle.com Oracle Solaris Platform Engineering: X Window System ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: Are we ready to tag release libXext 1.3.0?
I'm not aware of any fence sync issues that would hold up a release. Everything should be ready to go. Thanks, -James nvpublic On 5/5/11 7:09 PM, Alan Coopersmith alan.coopersm...@oracle.com wrote: It looks like we've still not done a release of libXext with the new XSyncAwaitFence() API yet, even though the proto server were released a while ago - is there anything remaining to do there or any reason not to go ahead and make a libXext 1.3.0 release? -- -Alan Coopersmith-alan.coopersm...@oracle.com Oracle Solaris Platform Engineering: X Window System ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: RandR 1.4 restart
On Friday 04 March 2011 11:43:05 pm Keith Packard wrote: * PGP Signed by an unknown key On Fri, 4 Mar 2011 16:47:45 -0800, James Jones jajo...@nvidia.com wrote: On 3/1/11 6:56 PM, James Jones jajo...@nvidia.com wrote: On Tuesday 01 March 2011 08:02:24 Keith Packard wrote: *snip* Scanout pixmaps get resized automatically when the associated crtc gets a new mode. This lets a compositing manager deal with the scanout pixmap creation while separate screen configuration applications deal with mode setting. Of course, internally, this is done by creating a new scanout pixmap and pointing the existing XID at the new object. (Hrm. I wonder if there are implications for DRI2/GLX/EGL here...) I looked over the rest of the spec changes, and spent some more time thinking about how bad it would be for GLX/EGL to have pixmaps resize. It looks pretty heinous. A lot of the badness comes from texture_from_pixmap/EGLimage extensions. If the pixmap is bound to a texture or EGL image, the size is derived from that pixmap. At least for GLX pixmaps, whether you want to use non-power-of-two textures (with mipmapping support), normal power of two textures (with mipmapping support), or rectangle textures (no mip-mapping, different texel coordinate system) depends on the size of the texture as well. The texture target is selected at GLX pixmap creation time, so just re-binding the pixmap wouldn't be sufficient to update all state. Remember that internally (at least at this point), the pixmap *isn't* getting resized -- a new pixmap is allocated and automagically assigned to the crtc as a scanout pixmap, and then the pixmap ID is switched from the old scanout pixmap to the new one. So, if you've created a resource which references the pixmap inside the server, things should 'just work'. Any client-side reference which ends up sticking the pixmap ID on the wire will not work though. OK, I thought you wanted to completely hide the resize from applications. If the intent is to force GLX clients to re-create their GLX pixmaps when the underlying X pixmap resizes, then the design sounds clean, and should work fine as long as no one goes in and tries to optimize the destroy/create out of the server code. Is there some way to bake that into the protocol spec so such an optimization would be non-compliant? It seems a little ugly to require clients to know RandR events can make certain GLX pixmaps no longer refer to the same resource they were created against, but this is admittedly a special case, and one that shouldn't break any existing applications. As an alternative to resizing the scannout pixmap, could you organize the protocol such that when a randr 1.4 composite manager is running, requests to change to a pre-validated resolution are redirected to the composite manager, based on something like SubstructureRedirectMask? The composite manager would then create a new crtc pixmap if necessary and apply the mode. I haven't thought this through in great depth yet, or discussed with anyone else at NVIDIA. Error conditions might be hard to get right in particular. I thought about this and it looked really ugly. Essentially, the entire mode set must be pend waiting for the compositing manager to deal with it. Which means either doing the whole redirection request, including packing up the entire mode set operation and handing it to the compositing manager to re-execute, or blocking the RandR application inside the server waiting for the compositing manager to reply. The former would be a fairly significant change for RandR applications, requiring that they pend on an event before continuing. The latter suffers from the usual live-lock adventure if the RandR application has grabbed a server lock. At least the server lock isn't required any more as we've got the atomic 'do everything' RandR operation now. Agreed, those problems do sound harder to overcome. I hand-waved myself past error-handling and replies when I thought this suggestion through. I decided on the pixmap resizing as the least evil of these options, I'd love to know how to make this work cleanly with GLX pixmaps. I don't know how to improve the interaction, but it sounds acceptable to me within the constraints I mention above. An explicit pixmap changed event (I assume these resizes won't generate configure-notify on a pixmap some how...) might make things clearer, but it might be overkill. I think mentioning the issue in the protocol updates would be valuable though, so future GLX/EGL/VDPAU-based composite manager coders don't need to dig up this thread to understand what's going on with their CRTC pixmaps. Thanks, -James ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: RandR 1.4 restart
On Thursday 03 March 2011 4:14:04 pm Soeren Sandmann wrote: James Jones jajo...@nvidia.com writes: With a scheme like this, the Composite extension itself would become simply a way to support legacy applications since window redirection doesn't really mean anything for InputOnly windows. I would love to see the composite extension extended rather than replaced. What I meant by simply a way to support legacy applications was just that with the scheme described, if all applications were to magically be ported over to the new way, there wouldn't be any need for Composite at all, because there simply wouldn't be any InputOutput windows to redirect. I think the API changes needed to implement the basics of this would be pretty minimal. I believe the only new feature needed in the X server is a client-visible refcount on Pictures, and this is only so that the compositing manager can keep the pictures in the update requests around without copying them. Interesting. I'm not really sold on the switch to InputOnly windows though. It sounds very elegant in theory, but I don't like the idea of apps needing to use a separate codepath depending on whether a composite manager is running, and I'm not convinced it doesn't have other side effects. I'll definitely have to give it some more thought though. Thanks, -James Soren ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: RandR 1.4 restart
On 3/1/11 6:56 PM, James Jones jajo...@nvidia.com wrote: On Tuesday 01 March 2011 08:02:24 Keith Packard wrote: *snip* Scanout pixmaps get resized automatically when the associated crtc gets a new mode. This lets a compositing manager deal with the scanout pixmap creation while separate screen configuration applications deal with mode setting. Of course, internally, this is done by creating a new scanout pixmap and pointing the existing XID at the new object. (Hrm. I wonder if there are implications for DRI2/GLX/EGL here...) I looked over the rest of the spec changes, and spent some more time thinking about how bad it would be for GLX/EGL to have pixmaps resize. It looks pretty heinous. A lot of the badness comes from texture_from_pixmap/EGLimage extensions. If the pixmap is bound to a texture or EGL image, the size is derived from that pixmap. At least for GLX pixmaps, whether you want to use non-power-of-two textures (with mipmapping support), normal power of two textures (with mipmapping support), or rectangle textures (no mip-mapping, different texel coordinate system) depends on the size of the texture as well. The texture target is selected at GLX pixmap creation time, so just re-binding the pixmap wouldn't be sufficient to update all state. As an alternative to resizing the scannout pixmap, could you organize the protocol such that when a randr 1.4 composite manager is running, requests to change to a pre-validated resolution are redirected to the composite manager, based on something like SubstructureRedirectMask? The composite manager would then create a new crtc pixmap if necessary and apply the mode. I haven't thought this through in great depth yet, or discussed with anyone else at NVIDIA. Error conditions might be hard to get right in particular. Thanks, -James Yeah, I hadn't thought about that, that's a mess. GLX has a separate name for the pixmap, so any GLX pixmaps are still going to refer to the old pixmap. At the very least, the function that frees and reallocates the new pixmap in X should be wrappable, so GLX can hook in and update things. However, this means drivers can no longer rely on a GLX pixmap's storage not moving after it is created. I think that's handleable, but it will muddy a lot of otherwise clean code. I'll try to make time to look over randr 1.4 in more depth in the next couple of days. Thanks, -James ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel nvpublic ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: RandR 1.4 restart
On Tuesday 01 March 2011 14:48:44 Soeren Sandmann wrote: Keith Packard kei...@keithp.com writes: On Tue, 01 Mar 2011 20:12:14 +0100, Soeren Sandmann sandm...@cs.au.dk wrote: Presumably the main use case for this is fullscreen video. When using a compositing manager, any full-screen window for video or graphics would be 'un-redirected', eliminating any cost of using a compositing manager. And, of course, with DRI2, applications would be using swapping instead of copying for window update. I think you can do better than that by scanning out from a YUV pixmap. This avoids the RGB conversion on hardware that has the capability, and it does so without the application doing anything special. In any case, if you read the rest of the email, the setup described there avoids a whole bunch of copying in all cases, not just he fullscreen case. Also, getting the unredirect/redirect to work without causing a bunch of expose events and related flickering is hard. It's possible now in most cases with Ville's patches to avoid the extra mapping in composite, but I'm still not convinced it works in the general case. Thanks, -James Soren ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: RandR 1.4 restart
On Tuesday 01 March 2011 11:12:14 Soeren Sandmann wrote: Ville Syrjälä ville.syrj...@nokia.com writes: On Mon, Feb 28, 2011 at 05:29:56PM -0800, ext Keith Packard wrote: Ok, let's try to get a bit of protocol review, then look at the library API, then the server internal APIs and finally the server implementation. Most of the code already exists, so this shouldn't take a terribly long time. I've cleaned up the protocol a bit, reducing the changes so that we've got only one 'set' and one 'get' request, each of which do 'everything' except deal with output properties. The separate requests to set and query the sprite transforms are gone. For the library changes, I'd like to know is whether I should emulate the new SetCrtcConfigs interface using old requests on old servers. That would involve duplicating a bit of structure from the insides of the X server, but would mean that applications could switch to the new interface and not worry about preserving compatibility with the old. Here's a diff from 1.3.2 of just the protocol specification. Please see if this looks reasonable from a protocol perspective. So what about also allowing windows to use the scanout pixmaps as their backing pixmap? I'm mainly interested in something that would allow unredirected 32bpp windows on a 16bpp screen. Presumably the main use case for this is fullscreen video. IMO, we need to move to a model where - The backing store for a window is managed by the compositing manager, and not by the X server. - Applications send update requests directly to the compositing manager (through ClientMessages or the like) in the form of Picture IDs plus coordinates for a position where those pictures are to be copied. - Applications either tell the compositing manager what format the window pixmap should be, or they let the compositing make that decision itself based on the root format and/or the formats of the updates. In this model, toplevel windows would be InputOnly and not InputOutput as they are now. Interesting. I've been talking up almost this exact idea for a year and a half now and never gotten much feedback on it, so I'm surprised to hear you've got very similar ideas. More comments below, and for reference, yes I'm referring to the ideas Aaron presented at XDC 2009 again, available here: http://people.freedesktop.org/~aplattner/x-presentation-and- synchronization.pdf Advantages include: - Completely tear-free updates because the compositing manager can delay updating the window pixmaps until the application signals that it has finished drawing a frame. (We may need client-visible refcounts on pictures for this to work). - With the RandR 1.4 SetCRTCPixmap, almost all the current copying goes away. For reference, here are the copies that may currently take place: - Application draws into offscreen pixmap - Application draws offscreen pixmap into redirected window - Redirected window is copied onto redirected window frame (if the frame has a different depth than the window) - Redirected window frame is copied onto offscreen pixmap by compositing manager - Offscreen pixmap is copied into shadow framebuffer by X server - Shadow framebuffer is copied into real framebuffer In the new model, the application draws into offscreen pixmaps, which are copied into backing pixmaps, which are copied directly into the (eventual) framebuffer. Enterprising compositing managers could even try to reuse the framebuffer as backing store for the parts of windows that are visible. Our proposal shares all these advantages, plus has the following: -It defines a more robust presentation framework for X. -Doesn't require a composite manager. It allows falling back to server-side rendering without losing many of the presentation benefits (such as tear-free updates). -Puts full control of backing store allocation and management in application's hands, rather than X or the composite manager. Legacy applications would behave as they do today, but applications that chose to take advantage of the new extensions could specify how many offscreen backing pixmaps they wanted, whether they want tear-free updates, timed updates (for smooth animation control), etc. -Integrates well with GLX/EGL. For full-screen video in particular, if Render were to gain support for YUV formats, the advantages are significant: - The video player could submit YUV pictures directly to the compositing manager, which could then decide how to best scale it and convert to RGB. An obvious option would be scanning them out directly if the window is fullscreen and the hardware supports it. - The backing pixmap could be updated with just the blocks that actually changed since the last frame (as provided by
Re: RandR 1.4 restart
On Tuesday 01 March 2011 18:35:14 Keith Packard wrote: * PGP Signed by an unknown key On Tue, 1 Mar 2011 18:11:24 -0800, James Jones jajo...@nvidia.com wrote: Also, getting the unredirect/redirect to work without causing a bunch of expose events and related flickering is hard. It's possible now in most cases with Ville's patches to avoid the extra mapping in composite, but I'm still not convinced it works in the general case. I think we want to solve that in Composite, not RandR though, right? I just mention it as a reminder that it can't be taken for granted that composite managers are actually unredirecting fullscreen windows right now. In general, I think most of what Soeren talks about should be handled within the composite framework, but the distinction between randr crtc pixmaps and composite backing pixmaps is getting thin enough that both should be kept in mind when working on either of the two. Thanks, -James ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
Re: RandR 1.4 restart
On Tuesday 01 March 2011 08:02:24 Keith Packard wrote: *snip* Scanout pixmaps get resized automatically when the associated crtc gets a new mode. This lets a compositing manager deal with the scanout pixmap creation while separate screen configuration applications deal with mode setting. Of course, internally, this is done by creating a new scanout pixmap and pointing the existing XID at the new object. (Hrm. I wonder if there are implications for DRI2/GLX/EGL here...) Yeah, I hadn't thought about that, that's a mess. GLX has a separate name for the pixmap, so any GLX pixmaps are still going to refer to the old pixmap. At the very least, the function that frees and reallocates the new pixmap in X should be wrappable, so GLX can hook in and update things. However, this means drivers can no longer rely on a GLX pixmap's storage not moving after it is created. I think that's handleable, but it will muddy a lot of otherwise clean code. I'll try to make time to look over randr 1.4 in more depth in the next couple of days. Thanks, -James ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v2)] X Sync Cleanups
Various cleanups identified during review of the X Sync Fence Object patches. -Correctly handle failure of AddResource() -Don't assert when data structures are corrupt. Instead, use a new helper function to check for counter sync objects when they're expected, and warn if the type is wrong. -Use the default switch label rather than reimplementing it. -Re-introduce cast of result of dixAllocateObjectWithPrivate() to kill an incompatible pointer type warning. -Remove comments claiming protocol updates are needed. One wasn't true and the other was addressed with a xextproto change. -Return BadFence, not BadCounter from XSyncAwaitFence() Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Keith Packard kei...@keithp.com --- Xext/sync.c | 138 ++ 1 files changed, 81 insertions(+), 57 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index ab8f20d..29e729d 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -91,6 +91,14 @@ static RESTYPE RTFence; static int SyncNumSystemCounters = 0; static SyncCounter **SysCounterList = NULL; +static const char *WARN_INVALID_COUNTER_COMPARE = +Warning: Non-counter XSync object using Counter-only\n + comparison. Result will never be true.\n; + +static const char *WARN_INVALID_COUNTER_ALARM = +Warning: Non-counter XSync object used in alarm. This is\n + the result of a programming error in the X server.\n; + #define IsSystemCounter(pCounter) \ (pCounter (pCounter-sync.client == NULL)) @@ -104,6 +112,18 @@ static void SyncInitServerTime(void); static void SyncInitIdleTime(void); +static Bool +SyncCheckWarnIsCounter(const SyncObject* pSync, const char *warning) +{ +if (pSync (SYNC_COUNTER != pSync-type)) +{ + ErrorF(%s, warning); + ErrorF( Counter type: %d\n, pSync-type); + return FALSE; +} + +return TRUE; +} /* Each counter maintains a simple linked list of triggers that are * interested in the counter. The two functions below are used to @@ -191,7 +211,6 @@ SyncAddTriggerToSyncObject(SyncTrigger *pTrigger) return Success; } - /* Below are five possible functions that can be plugged into * pTrigger-CheckTrigger for counter sync objects, corresponding to * the four possible test-types, and the one possible function that @@ -212,7 +231,12 @@ SyncCheckTriggerPositiveComparison(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); + +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (!SyncCheckWarnIsCounter(pTrigger-pSync, WARN_INVALID_COUNTER_COMPARE)) + return FALSE; + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -224,7 +248,11 @@ SyncCheckTriggerNegativeComparison(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (!SyncCheckWarnIsCounter(pTrigger-pSync, WARN_INVALID_COUNTER_COMPARE)) + return FALSE; + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -236,7 +264,11 @@ SyncCheckTriggerPositiveTransition(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (!SyncCheckWarnIsCounter(pTrigger-pSync, WARN_INVALID_COUNTER_COMPARE)) + return FALSE; + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -249,7 +281,11 @@ SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (!SyncCheckWarnIsCounter(pTrigger-pSync, WARN_INVALID_COUNTER_COMPARE)) + return FALSE; + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -326,14 +362,6 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, } else { - if (pTrigger-test_type != XSyncPositiveTransition - pTrigger-test_type != XSyncNegativeTransition - pTrigger-test_type != XSyncPositiveComparison - pTrigger-test_type != XSyncNegativeComparison) - { - client-errorValue = pTrigger-test_type; - return BadValue; - } /* select appropriate CheckTrigger function */ switch (pTrigger-test_type) @@ -350,6 +378,9 @@ SyncInitTrigger(ClientPtr client
[PATCH xserver (v3)] X Sync Cleanups
Various cleanups identified during review of the X Sync Fence Object patches. -Correctly handle failure of AddResource() -Don't assert when data structures are corrupt. Instead, use a new helper function to check for counter sync objects when they're expected, and warn if the type is wrong. -Use the default switch label rather than reimplementing it. -Re-introduce cast of result of dixAllocateObjectWithPrivate() to kill an incompatible pointer type warning. -Remove comments claiming protocol updates are needed. One wasn't true and the other was addressed with a xextproto change. -Return BadFence, not BadCounter from XSyncAwaitFence() Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Keith Packard kei...@keithp.com --- Xext/sync.c | 142 +++--- 1 files changed, 86 insertions(+), 56 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index ab8f20d..fd0dd70 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -90,6 +90,16 @@ static RESTYPE RTAlarmClient; static RESTYPE RTFence; static int SyncNumSystemCounters = 0; static SyncCounter **SysCounterList = NULL; +static int SyncNumInvalidCounterWarnings = 0; +#define MAX_INVALID_COUNTER_WARNINGS 5 + +static const char *WARN_INVALID_COUNTER_COMPARE = +Warning: Non-counter XSync object using Counter-only\n + comparison. Result will never be true.\n; + +static const char *WARN_INVALID_COUNTER_ALARM = +Warning: Non-counter XSync object used in alarm. This is\n + the result of a programming error in the X server.\n; #define IsSystemCounter(pCounter) \ (pCounter (pCounter-sync.client == NULL)) @@ -104,6 +114,22 @@ static void SyncInitServerTime(void); static void SyncInitIdleTime(void); +static Bool +SyncCheckWarnIsCounter(const SyncObject* pSync, const char *warning) +{ +if (pSync (SYNC_COUNTER != pSync-type)) +{ + if (SyncNumInvalidCounterWarnings++ MAX_INVALID_COUNTER_WARNINGS) + { + ErrorF(%s, warning); + ErrorF( Counter type: %d\n, pSync-type); + } + + return FALSE; +} + +return TRUE; +} /* Each counter maintains a simple linked list of triggers that are * interested in the counter. The two functions below are used to @@ -212,7 +238,11 @@ SyncCheckTriggerPositiveComparison(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (!SyncCheckWarnIsCounter(pTrigger-pSync, WARN_INVALID_COUNTER_COMPARE)) + return FALSE; + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -224,7 +254,11 @@ SyncCheckTriggerNegativeComparison(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (!SyncCheckWarnIsCounter(pTrigger-pSync, WARN_INVALID_COUNTER_COMPARE)) + return FALSE; + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -236,7 +270,11 @@ SyncCheckTriggerPositiveTransition(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (!SyncCheckWarnIsCounter(pTrigger-pSync, WARN_INVALID_COUNTER_COMPARE)) + return FALSE; + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -249,7 +287,11 @@ SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (!SyncCheckWarnIsCounter(pTrigger-pSync, WARN_INVALID_COUNTER_COMPARE)) + return FALSE; + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -326,14 +368,6 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, } else { - if (pTrigger-test_type != XSyncPositiveTransition - pTrigger-test_type != XSyncNegativeTransition - pTrigger-test_type != XSyncPositiveComparison - pTrigger-test_type != XSyncNegativeComparison) - { - client-errorValue = pTrigger-test_type; - return BadValue; - } /* select appropriate CheckTrigger function */ switch (pTrigger-test_type) @@ -350,6 +384,9 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, case
Re: [PATCH 2/2] mi: Sync: Don't free managed screen private
On 12/17/10 8:57 AM, Daniel Stone dan...@fooishbar.org wrote: misync allocates space for its screen private with dixRegisterPrivateKey, which means it doesn't have to free it at CloseScreen time; doing so will, in fact, result in a crash. Signed-off-by: Daniel Stone dan...@fooishbar.org --- miext/sync/misync.c |1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/miext/sync/misync.c b/miext/sync/misync.c index bcc68a2..50226d9 100644 --- a/miext/sync/misync.c +++ b/miext/sync/misync.c @@ -167,7 +167,6 @@ SyncCloseScreen (int i, ScreenPtr pScreen) SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); pScreen-CloseScreen = pScreenPriv-CloseScreen; -free(pScreenPriv); return (*pScreen-CloseScreen) (i, pScreen); } -- 1.7.2.3 Reviewed-by: James Jones jajo...@nvidia.com Thanks, -James ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel nvpublic ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xextproto] Document another error for XSyncAwaitFence
XSyncAwaitFence can generate BadValue if the fence list argument is empty. Document this in the spec. --- specs/sync.xml |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/specs/sync.xml b/specs/sync.xml index 44a6b2c..aaad323 100644 --- a/specs/sync.xml +++ b/specs/sync.xml @@ -885,14 +885,15 @@ fence does not name a valid fence. listitem literallayout class=monospaced fence-list: LISTofFENCE -Errors: functionFence/function,functionAlloc/function +Errors: functionFence/function,functionAlloc/function,functionValue/function /literallayout para When this request is executed, the processing of further requests for the client is blocked until one or more of the fences in fence-list reaches the triggered state. If any of the fences are already in the triggered state, request processing resumes immediately. A functionFence/function error -is generated if any member of fence-list does not name a valid fence. +is generated if any member of fence-list does not name a valid fence. A +functionValue/function error is generated if fence-list is empty. /para /listitem /varlistentry -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver] X Sync Cleanups
Various cleanups identified during review of the X Sync Fence Object patches. -Correctly handle failure of AddResource() -Don't assert when data structures are corrupt. -Use the default switch label rather than reimplementing it. -Re-introduce cast of result of dixAllocateObjectWithPrivate() to kill an incompatible pointer type warning. -Remove comments claiming protocol updates are needed. One wasn't true and the other was addressed with a xextproto change. -Return BadFence, not BadCounter from XSyncAwaitFence() Signed-off-by: James Jones jajo...@nvidia.com --- Xext/sync.c | 166 --- 1 files changed, 112 insertions(+), 54 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index ab8f20d..c636263 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -212,7 +212,17 @@ SyncCheckTriggerPositiveComparison(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); + +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (pTrigger-pSync (SYNC_COUNTER != pTrigger-pSync-type)) +{ + ErrorF(Warning: Non-counter XSync object using Counter-only\n); + ErrorF( comparison. Result will never be true.\n); + ErrorF( Counter type: %d\n, pTrigger-pSync-type); + return FALSE; +} + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -224,7 +234,16 @@ SyncCheckTriggerNegativeComparison(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (pTrigger-pSync (SYNC_COUNTER != pTrigger-pSync-type)) +{ + ErrorF(Warning: Non-counter XSync object using Counter-only\n); + ErrorF( comparison. Result will never be true.\n); + ErrorF( Counter type: %d\n, pTrigger-pSync-type); + return FALSE; +} + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -236,7 +255,16 @@ SyncCheckTriggerPositiveTransition(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (pTrigger-pSync (SYNC_COUNTER != pTrigger-pSync-type)) +{ + ErrorF(Warning: Non-counter XSync object using Counter-only\n); + ErrorF( comparison. Result will never be true.\n); + ErrorF( Counter type: %d\n, pTrigger-pSync-type); + return FALSE; +} + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -249,7 +277,16 @@ SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval) { SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +/* Non-counter sync objects should never get here because they + * never trigger this comparison. */ +if (pTrigger-pSync (SYNC_COUNTER != pTrigger-pSync-type)) +{ + ErrorF(Warning: Non-counter XSync object using Counter-only\n); + ErrorF( comparison. Result will never be true.\n); + ErrorF( Counter type: %d\n, pTrigger-pSync-type); + return FALSE; +} + pCounter = (SyncCounter *)pTrigger-pSync; return (pCounter == NULL || @@ -326,14 +363,6 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, } else { - if (pTrigger-test_type != XSyncPositiveTransition - pTrigger-test_type != XSyncNegativeTransition - pTrigger-test_type != XSyncPositiveComparison - pTrigger-test_type != XSyncNegativeComparison) - { - client-errorValue = pTrigger-test_type; - return BadValue; - } /* select appropriate CheckTrigger function */ switch (pTrigger-test_type) @@ -350,6 +379,9 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, case XSyncNegativeComparison: pTrigger-CheckTrigger = SyncCheckTriggerNegativeComparison; break; + default: + client-errorValue = pTrigger-test_type; + return BadValue; } } } @@ -402,7 +434,13 @@ SyncSendAlarmNotifyEvents(SyncAlarm *pAlarm) SyncTrigger *pTrigger = pAlarm-trigger; SyncCounter *pCounter; -assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +if (pTrigger-pSync (SYNC_COUNTER != pTrigger-pSync-type)) +{ + ErrorF(Warning: Non-counter XSync object used in alarm. This is\n); + ErrorF( the result
[PATCH xextproto] Document another error for XSyncAwaitFence (Resend)
Resend includes sign-off. XSyncAwaitFence can generate BadValue if the fence list argument is empty. Document this in the spec. Signed-off-by: James Jones jajo...@nvidia.com --- specs/sync.xml |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/specs/sync.xml b/specs/sync.xml index 44a6b2c..aaad323 100644 --- a/specs/sync.xml +++ b/specs/sync.xml @@ -885,14 +885,15 @@ fence does not name a valid fence. listitem literallayout class=monospaced fence-list: LISTofFENCE -Errors: functionFence/function,functionAlloc/function +Errors: functionFence/function,functionAlloc/function,functionValue/function /literallayout para When this request is executed, the processing of further requests for the client is blocked until one or more of the fences in fence-list reaches the triggered state. If any of the fences are already in the triggered state, request processing resumes immediately. A functionFence/function error -is generated if any member of fence-list does not name a valid fence. +is generated if any member of fence-list does not name a valid fence. A +functionValue/function error is generated if fence-list is empty. /para /listitem /varlistentry -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v4) 05/10] Move some sync code to miext
As a precursor to the fence sync object video driver and extension API, move some code from Xext to miext/sync. Most of this is just code to set up the build system to include the new directory. No functional code is added in this change. Signed-off-by: James Jones jajo...@nvidia.com --- COPYING|2 +- Xext/sync.c|1 - Xext/syncsrv.h | 44 ++- configure.ac | 21 +++- miext/Makefile.am |4 +- miext/sync/Makefile.am | 14 miext/sync/misync.c| 25 +++ miext/sync/misync.h| 31 +++ miext/sync/misyncstr.h | 78 9 files changed, 166 insertions(+), 54 deletions(-) create mode 100644 miext/sync/Makefile.am create mode 100644 miext/sync/misync.c create mode 100644 miext/sync/misync.h create mode 100644 miext/sync/misyncstr.h diff --git a/COPYING b/COPYING index 3fb06b8..3aad5fa 100644 --- a/COPYING +++ b/COPYING @@ -14,7 +14,7 @@ Copyright © 2006-2007 Intel Corporation Copyright © 2006 Nokia Corporation Copyright © 2006-2008 Peter Hutterer Copyright © 2006 Adam Jackson -Copyright © 2009 NVIDIA Corporation +Copyright © 2009-2010 NVIDIA Corporation Copyright © 1999 Keith Packard Copyright © 2007-2009 Red Hat, Inc. Copyright © 2005-2008 Daniel Stone diff --git a/Xext/sync.c b/Xext/sync.c index d17a752..e5bc64f 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2192,7 +2192,6 @@ SyncResetProc(ExtensionEntry *extEntry) RTCounter = 0; } - /* * ** Initialise the extension. */ diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 64e42cd..aa7dfb9 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -51,24 +51,8 @@ PERFORMANCE OF THIS SOFTWARE. #ifndef _SYNCSRV_H_ #define _SYNCSRV_H_ -#define CARD64 XSyncValue /* XXX temporary! need real 64 bit values for Alpha */ - -/* Sync object types */ -#define SYNC_COUNTER 0 - -typedef struct _SyncObject { -ClientPtr client; /* Owning client. 0 for system counters */ -struct _SyncTriggerList *pTriglist;/* list of triggers */ -XIDid; /* resource ID */ -unsigned char type; /* SYNC_* */ -Bool beingDestroyed; /* in process of going away */ -} SyncObject; - -typedef struct _SyncCounter { -SyncObject sync; /* Common sync object data */ -CARD64 value; /* counter value */ -struct _SysCounterInfo *pSysCounterInfo; /* NULL if not a system counter */ -} SyncCounter; +#include misync.h +#include misyncstr.h /* * The System Counter interface @@ -100,29 +84,6 @@ typedef struct _SysCounterInfo { -typedef struct _SyncTrigger { -SyncObject *pSync; -CARD64 wait_value; /* wait value */ -unsigned int value_type; /* Absolute or Relative */ -unsigned int test_type;/* transition or Comparision type */ -CARD64 test_value; /* trigger event threshold value */ -Bool (*CheckTrigger)( - struct _SyncTrigger * /*pTrigger*/, - CARD64 /*newval*/ - ); -void (*TriggerFired)( - struct _SyncTrigger * /*pTrigger*/ - ); -void (*CounterDestroyed)( - struct _SyncTrigger * /*pTrigger*/ - ); -} SyncTrigger; - -typedef struct _SyncTriggerList { -SyncTrigger *pTrigger; -struct _SyncTriggerList *next; -} SyncTriggerList; - typedef struct _SyncAlarmClientList { ClientPtr client; XIDdelete_id; @@ -179,6 +140,7 @@ extern void SyncChangeCounter( extern void SyncDestroySystemCounter( pointer pCounter ); + extern void InitServertime(void); extern void SyncExtensionInit(void); diff --git a/configure.ac b/configure.ac index a80a13f..c6f9b2f 100644 --- a/configure.ac +++ b/configure.ac @@ -1353,6 +1353,8 @@ FB_LIB='$(top_builddir)/fb/libfb.la' FB_INC='-I$(top_srcdir)/fb' MIEXT_SHADOW_INC='-I$(top_srcdir)/miext/shadow' MIEXT_SHADOW_LIB='$(top_builddir)/miext/shadow/libshadow.la' +MIEXT_SYNC_INC='-I$(top_srcdir)/miext/sync' +MIEXT_SYNC_LIB='$(top_builddir)/miext/sync/libsync.la' CORE_INCS='-I$(top_srcdir)/include -I$(top_builddir)/include' # SHA1 hashing @@ -1492,7 +1494,7 @@ AC_EGREP_CPP([I_AM_SVR4],[ AC_DEFINE([SVR4],1,[Define to 1 on systems derived from System V Release 4]) AC_MSG_RESULT([yes])], AC_MSG_RESULT([no])) -XSERVER_CFLAGS=$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC $RANDR_INC $FB_INC +XSERVER_CFLAGS=$XSERVER_CFLAGS $CORE_INCS $XEXT_INC $COMPOSITE_INC $DAMAGE_INC $FIXES_INC $XI_INC $MI_INC $MIEXT_SYNC_INC $MIEXT_SHADOW_INC $MIEXT_LAYER_INC $MIEXT_DAMAGE_INC $RENDER_INC
[PATCH xserver (v4) 02/10] Create SyncObject base type.
SyncObject is now the base type for SyncCounter. Data to be used by all sync types is stored in the base object. SyncCounter can be safely cast to SyncObject, and a SyncObject can be cast to the correct type based on SyncObject::type. Signed-off-by: James Jones jajo...@nvidia.com --- Xext/sync.c| 95 Xext/syncsrv.h | 16 +++-- 2 files changed, 73 insertions(+), 38 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 4da06ac..d5187dd 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -89,7 +89,7 @@ static int SyncNumSystemCounters = 0; static SyncCounter **SysCounterList = NULL; #define IsSystemCounter(pCounter) \ -(pCounter (pCounter-client == NULL)) +(pCounter (pCounter-sync.client == NULL)) /* these are all the alarm attributes that pertain to the alarm's trigger */ #define XSyncCAAllTrigger \ @@ -118,7 +118,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) return; pPrev = NULL; -pCur = pTrigger-pCounter-pTriglist; +pCur = pTrigger-pCounter-sync.pTriglist; while (pCur) { @@ -127,7 +127,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) if (pPrev) pPrev-next = pCur-next; else - pTrigger-pCounter-pTriglist = pCur-next; + pTrigger-pCounter-sync.pTriglist = pCur-next; free(pCur); break; @@ -151,7 +151,7 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) return Success; /* don't do anything if it's already there */ -for (pCur = pTrigger-pCounter-pTriglist; pCur; pCur = pCur-next) +for (pCur = pTrigger-pCounter-sync.pTriglist; pCur; pCur = pCur-next) { if (pCur-pTrigger == pTrigger) return Success; @@ -161,8 +161,8 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) return BadAlloc; pCur-pTrigger = pTrigger; -pCur-next = pTrigger-pCounter-pTriglist; -pTrigger-pCounter-pTriglist = pCur; +pCur-next = pTrigger-pCounter-sync.pTriglist; +pTrigger-pCounter-sync.pTriglist = pCur; if (IsSystemCounter(pTrigger-pCounter)) SyncComputeBracketValues(pTrigger-pCounter); @@ -390,14 +390,14 @@ SyncSendCounterNotifyEvents(ClientPtr client, SyncAwait **ppAwait, SyncTrigger *pTrigger = (*ppAwait)-trigger; pev-type = SyncEventBase + XSyncCounterNotify; pev-kind = XSyncCounterNotify; - pev-counter = pTrigger-pCounter-id; + pev-counter = pTrigger-pCounter-sync.id; pev-wait_value_lo = XSyncValueLow32(pTrigger-test_value); pev-wait_value_hi = XSyncValueHigh32(pTrigger-test_value); pev-counter_value_lo = XSyncValueLow32(pTrigger-pCounter-value); pev-counter_value_hi = XSyncValueHigh32(pTrigger-pCounter-value); pev-time = currentTime.milliseconds; pev-count = num_events - i - 1; /* events remaining */ - pev-destroyed = pTrigger-pCounter-beingDestroyed; + pev-destroyed = pTrigger-pCounter-sync.beingDestroyed; } /* swapping will be taken care of by this */ WriteEventsToClient(client, num_events, (xEvent *)pEvents); @@ -532,7 +532,7 @@ SyncAwaitTriggerFired(SyncTrigger *pTrigger) * always generated if the counter for one of the triggers is * destroyed. */ - if (pAwait-trigger.pCounter-beingDestroyed) + if (pAwait-trigger.pCounter-sync.beingDestroyed) { ppAwait[num_events++] = pAwait; continue; @@ -600,7 +600,7 @@ SyncChangeCounter(SyncCounter *pCounter, CARD64 newval) pCounter-value = newval; /* run through triggers to see if any become true */ -for (ptl = pCounter-pTriglist; ptl; ptl = pnext) +for (ptl = pCounter-sync.pTriglist; ptl; ptl = pnext) { pnext = ptl-next; if ((*ptl-pTrigger-CheckTrigger)(ptl-pTrigger, oldval)) @@ -692,7 +692,8 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm *pAlarm, Mask mask, XSyncCounter counter; Mask origmask = mask; -counter = pAlarm-trigger.pCounter ? pAlarm-trigger.pCounter-id : None; +counter = + pAlarm-trigger.pCounter ? pAlarm-trigger.pCounter-sync.id : None; while (mask) { @@ -781,26 +782,52 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm *pAlarm, Mask mask, return Success; } - -static SyncCounter * -SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64 initialvalue) +static SyncObject * +SyncCreate(ClientPtr client, XID id, unsigned char type) { -SyncCounter *pCounter; +SyncObject *pSync; +RESTYPE resType; +unsigned long syncSize; -if (!(pCounter = malloc(sizeof(SyncCounter +switch (type) { +case SYNC_COUNTER: + resType = RTCounter; + syncSize = sizeof(SyncCounter); + break; +default: return NULL; +} -if (!AddResource(id, RTCounter, (pointer) pCounter)) +if (!(pSync = (SyncObject *)malloc(syncSize
[PATCH xserver (v4) 04/10] Factor out generic code from ProcSyncAwait()
In preparation for adding more sync object types that will need Await requests of their own, factor out some setup and finalization code from ProcSyncAwait() into SyncAwaitPrologue() and SyncAwaitEpilogue() Signed-off-by: James Jones jajo...@nvidia.com --- Xext/sync.c | 110 +++ 1 files changed, 65 insertions(+), 45 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 1a2d55d..d17a752 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -1465,6 +1465,66 @@ ProcSyncDestroyCounter(ClientPtr client) return Success; } +static SyncAwaitUnion* +SyncAwaitPrologue(ClientPtr client, int items) +{ +SyncAwaitUnion *pAwaitUnion; + +/* all the memory for the entire await list is allocated + * here in one chunk + */ +pAwaitUnion = malloc((items+1) * sizeof(SyncAwaitUnion)); +if (!pAwaitUnion) + return NULL; + +/* first item is the header, remainder are real wait conditions */ + +pAwaitUnion-header.delete_id = FakeClientID(client-index); +if (!AddResource(pAwaitUnion-header.delete_id, RTAwait, pAwaitUnion)) +{ + free(pAwaitUnion); + return NULL; +} + +pAwaitUnion-header.client = client; +pAwaitUnion-header.num_waitconditions = 0; + +return pAwaitUnion; +} + +static void +SyncAwaitEpilogue(ClientPtr client, int items, SyncAwaitUnion *pAwaitUnion) +{ +SyncAwait *pAwait; +int i; + +IgnoreClient(client); + +/* see if any of the triggers are already true */ + +pAwait = (pAwaitUnion+1)-await; /* skip over header */ +for (i = 0; i items; i++, pAwait++) +{ + CARD64 value; + + /* don't have to worry about NULL counters because the request +* errors before we get here out if they occur +*/ + switch (pAwait-trigger.pSync-type) { + case SYNC_COUNTER: + value = ((SyncCounter *)pAwait-trigger.pSync)-value; + break; + default: + XSyncIntToValue(value, 0); + } + + if ((*pAwait-trigger.CheckTrigger)(pAwait-trigger, value)) + { + (*pAwait-trigger.TriggerFired)(pAwait-trigger); + break; /* once is enough */ + } +} +} /* * ** Await @@ -1496,28 +1556,12 @@ ProcSyncAwait(ClientPtr client) return BadValue; } -pProtocolWaitConds = (xSyncWaitCondition *) stuff[1]; - -/* all the memory for the entire await list is allocated - * here in one chunk - */ -pAwaitUnion = malloc((items+1) * sizeof(SyncAwaitUnion)); -if (!pAwaitUnion) +if (!(pAwaitUnion = SyncAwaitPrologue(client, items))) return BadAlloc; -/* first item is the header, remainder are real wait conditions */ - -pAwaitUnion-header.delete_id = FakeClientID(client-index); -if (!AddResource(pAwaitUnion-header.delete_id, RTAwait, pAwaitUnion)) -{ - free(pAwaitUnion); - return BadAlloc; -} - /* don't need to do any more memory allocation for this request! */ -pAwaitUnion-header.client = client; -pAwaitUnion-header.num_waitconditions = 0; +pProtocolWaitConds = (xSyncWaitCondition *) stuff[1]; pAwait = (pAwaitUnion+1)-await; /* skip over header */ for (i = 0; i items; i++, pProtocolWaitConds++, pAwait++) @@ -1525,7 +1569,7 @@ ProcSyncAwait(ClientPtr client) if (pProtocolWaitConds-counter == None) /* XXX protocol change */ { /* this should take care of removing any triggers created by -* this request that have already been registered on counters +* this request that have already been registered on sync objects */ FreeResource(pAwaitUnion-header.delete_id, RT_NONE); client-errorValue = pProtocolWaitConds-counter; @@ -1546,7 +1590,7 @@ ProcSyncAwait(ClientPtr client) if (status != Success) { /* this should take care of removing any triggers created by -* this request that have already been registered on counters +* this request that have already been registered on sync objects */ FreeResource(pAwaitUnion-header.delete_id, RT_NONE); return status; @@ -1561,32 +1605,8 @@ ProcSyncAwait(ClientPtr client) pAwaitUnion-header.num_waitconditions++; } -IgnoreClient(client); - -/* see if any of the triggers are already true */ +SyncAwaitEpilogue(client, items, pAwaitUnion); -pAwait = (pAwaitUnion+1)-await; /* skip over header */ -for (i = 0; i items; i++, pAwait++) -{ - CARD64 value; - - /* don't have to worry about NULL counters because the request -* errors before we get here out if they occur -*/ - switch (pAwait-trigger.pSync-type) { - case SYNC_COUNTER: - value = ((SyncCounter *)pAwait-trigger.pSync)-value; - break; - default: - XSyncIntToValue(value, 0); - } - - if ((*pAwait
[PATCH xserver (v4) 07/10] Require xextproto 7.1.99
Subsequent changes rely on fence sync protocol in the sync extension. This protocol is only complete in xextproto version 7.1.99 and above. Signed-off-by: James Jones jajo...@nvidia.com --- configure.ac |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index c6f9b2f..0108541 100644 --- a/configure.ac +++ b/configure.ac @@ -791,7 +791,7 @@ WINDOWSWMPROTO=windowswmproto APPLEWMPROTO=applewmproto = 1.4 dnl Core modules for most extensions, et al. -SDK_REQUIRED_MODULES=[xproto = 7.0.17] [randrproto = 1.2.99.3] [renderproto = 0.11] [xextproto = 7.0.99.3] [inputproto = 1.9.99.902] [kbproto = 1.0.3] fontsproto +SDK_REQUIRED_MODULES=[xproto = 7.0.17] [randrproto = 1.2.99.3] [renderproto = 0.11] [xextproto = 7.1.99] [inputproto = 1.9.99.902] [kbproto = 1.0.3] fontsproto # Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc AC_SUBST(SDK_REQUIRED_MODULES) -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v4) 10/10] Expose Sync Fence Object protocol
Add the new protocol handlers for XSync 3.1 to the dispatch tables and report support for Sync protocol version 3.1. Signed-off-by: James Jones jajo...@nvidia.com --- Xext/sync.c | 24 include/protocol-versions.h |2 +- 2 files changed, 25 insertions(+), 1 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 6fcdd72..9145b1c 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2165,6 +2165,18 @@ ProcSyncDispatch(ClientPtr client) return ProcSyncSetPriority(client); case X_SyncGetPriority: return ProcSyncGetPriority(client); + case X_SyncCreateFence: + return ProcSyncCreateFence(client); + case X_SyncTriggerFence: + return ProcSyncTriggerFence(client); + case X_SyncResetFence: + return ProcSyncResetFence(client); + case X_SyncDestroyFence: + return ProcSyncDestroyFence(client); + case X_SyncQueryFence: + return ProcSyncQueryFence(client); + case X_SyncAwaitFence: + return ProcSyncAwaitFence(client); default: return BadRequest; } @@ -2477,6 +2489,18 @@ SProcSyncDispatch(ClientPtr client) return SProcSyncSetPriority(client); case X_SyncGetPriority: return SProcSyncGetPriority(client); + case X_SyncCreateFence: + return SProcSyncCreateFence(client); + case X_SyncTriggerFence: + return SProcSyncTriggerFence(client); + case X_SyncResetFence: + return SProcSyncResetFence(client); + case X_SyncDestroyFence: + return SProcSyncDestroyFence(client); + case X_SyncQueryFence: + return SProcSyncQueryFence(client); + case X_SyncAwaitFence: + return SProcSyncAwaitFence(client); default: return BadRequest; } diff --git a/include/protocol-versions.h b/include/protocol-versions.h index ce28797..1d33bdd 100644 --- a/include/protocol-versions.h +++ b/include/protocol-versions.h @@ -97,7 +97,7 @@ /* Sync */ #define SERVER_SYNC_MAJOR_VERSION 3 -#define SERVER_SYNC_MINOR_VERSION 0 +#define SERVER_SYNC_MINOR_VERSION 1 /* Windows WM */ #define SERVER_WINDOWSWM_MAJOR_VERSION 1 -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v4) 06/10] Add fence sync driver interface
-Add fence sync objects -Add fence sync devPrivates -Add a X sync module screen private -Add wrappable functions to create and destroy fence sync objects -Give fence sync objects wrappable functions to trigger, test, and reset their 'triggered' value. -Give fence sync objects wrappable functions to notify driver when adding/removing triggers to/ from the sync object. Signed-off-by: James Jones jajo...@nvidia.com --- Xext/sync.c |6 +- dix/privates.c |1 + hw/xfree86/loader/sdksyms.sh |3 + include/privates.h |1 + miext/sync/misync.c | 176 ++ miext/sync/misync.h | 46 +++ miext/sync/misyncstr.h | 12 +++- 7 files changed, 242 insertions(+), 3 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index e5bc64f..2615c27 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -59,7 +59,7 @@ PERFORMANCE OF THIS SOFTWARE. #include X11/X.h #include X11/Xproto.h #include X11/Xmd.h -#include misc.h +#include scrnintstr.h #include os.h #include extnsionst.h #include dixstruct.h @@ -2199,6 +2199,10 @@ void SyncExtensionInit(void) { ExtensionEntry *extEntry; +ints; + +for (s = 0; s screenInfo.numScreens; s++) + miSyncSetup(screenInfo.screens[s]); if (RTCounter == 0) { diff --git a/dix/privates.c b/dix/privates.c index 687fa7a..d651258 100644 --- a/dix/privates.c +++ b/dix/privates.c @@ -447,6 +447,7 @@ static const char *key_names[PRIVATE_LAST] = { [PRIVATE_GLYPH] = GLYPH, [PRIVATE_GLYPHSET] = GLYPHSET, [PRIVATE_PICTURE] = PICTURE, +[PRIVATE_SYNC_FENCE] = SYNC_FENCE, }; void diff --git a/hw/xfree86/loader/sdksyms.sh b/hw/xfree86/loader/sdksyms.sh index 4b3ed86..2135430 100755 --- a/hw/xfree86/loader/sdksyms.sh +++ b/hw/xfree86/loader/sdksyms.sh @@ -41,6 +41,9 @@ cat sdksyms.c EOF #include damage.h #include damagestr.h +/* miext/sync/Makefile.am */ +#include misync.h +#include misyncstr.h /* Xext/Makefile.am -- half is module, half is builtin */ /* diff --git a/include/privates.h b/include/privates.h index 9fb6ae8..7ef2cb7 100644 --- a/include/privates.h +++ b/include/privates.h @@ -51,6 +51,7 @@ typedef enum { PRIVATE_GLYPH, PRIVATE_GLYPHSET, PRIVATE_PICTURE, +PRIVATE_SYNC_FENCE, /* last private type */ PRIVATE_LAST, diff --git a/miext/sync/misync.c b/miext/sync/misync.c index 344810f..bcc68a2 100644 --- a/miext/sync/misync.c +++ b/miext/sync/misync.c @@ -21,5 +21,181 @@ * DEALINGS IN THE SOFTWARE. */ +#ifdef HAVE_DIX_CONFIG_H +#include dix-config.h +#endif + +#include scrnintstr.h #include misync.h #include misyncstr.h + +static DevPrivateKeyRec syncScreenPrivateKeyRec; +static DevPrivateKey syncScreenPrivateKey = syncScreenPrivateKeyRec; + +#define SYNC_SCREEN_PRIV(pScreen) \ +(SyncScreenPrivPtr) dixLookupPrivate(pScreen-devPrivates,\ +syncScreenPrivateKey) + +typedef struct _syncScreenPriv { +/* Wrappable sync-specific screen functions */ +SyncScreenFuncsRec funcs; + +/* Wrapped screen functions */ +CloseScreenProcPtr CloseScreen; +} SyncScreenPrivRec, *SyncScreenPrivPtr; + +/* Default implementations of the sync screen functions */ +void +miSyncScreenCreateFence(ScreenPtr pScreen, SyncFence* pFence, +Bool initially_triggered) +{ +(void)pScreen; + +pFence-triggered = initially_triggered; +} + +void miSyncScreenDestroyFence(ScreenPtr pScreen, SyncFence* pFence) +{ +(void)pScreen; +(void)pFence; +} + +/* Default implementations of the per-object functions */ +static void +miSyncFenceSetTriggered(SyncFence* pFence) +{ +pFence-triggered = TRUE; +} + +static void +miSyncFenceReset(SyncFence* pFence) +{ +pFence-triggered = FALSE; +} + +static Bool +miSyncFenceCheckTriggered(SyncFence* pFence) +{ +return pFence-triggered; +} + +static void +miSyncFenceAddTrigger(SyncTrigger* pTrigger) +{ +(void)pTrigger; + +return; +} + +static void +miSyncFenceDeleteTrigger(SyncTrigger* pTrigger) +{ +(void)pTrigger; + +return; +} + +/* Machine independent portion of the fence sync object implementation */ +void +miSyncInitFence(ScreenPtr pScreen, SyncFence* pFence, Bool initially_triggered) +{ +SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); +static const SyncFenceFuncsRec miSyncFenceFuncs = { + miSyncFenceSetTriggered, + miSyncFenceReset, + miSyncFenceCheckTriggered, + miSyncFenceAddTrigger, + miSyncFenceDeleteTrigger +}; + +pFence-pScreen = pScreen; +pFence-funcs = miSyncFenceFuncs; + +pScreenPriv-funcs.CreateFence(pScreen, pFence, initially_triggered); +} + +void +miSyncDestroyFence(SyncFence* pFence) +{ +ScreenPtr pScreen = pFence-pScreen; +SyncScreenPrivPtr pScreenPriv = SYNC_SCREEN_PRIV(pScreen); +SyncTriggerList *ptl
[PATCH xserver (v4) 09/10] Add XSyncAwaitFence() handler
-Add the actual ProcSyncAwaitFence() dispatch func -Add support for fence sync triggers. Signed-off-by: James Jones jajo...@nvidia.com --- Xext/sync.c| 183 ++-- Xext/syncsrv.h |1 - 2 files changed, 152 insertions(+), 32 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 8955a72..6fcdd72 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -147,6 +147,9 @@ SyncDeleteTriggerFromSyncObject(SyncTrigger *pTrigger) if (IsSystemCounter(pCounter)) SyncComputeBracketValues(pCounter); +} else if (SYNC_FENCE == pTrigger-pSync-type) { + SyncFence* pFence = (SyncFence*) pTrigger-pSync; + pFence-funcs.DeleteTrigger(pTrigger); } } @@ -180,23 +183,27 @@ SyncAddTriggerToSyncObject(SyncTrigger *pTrigger) if (IsSystemCounter(pCounter)) SyncComputeBracketValues(pCounter); +} else if (SYNC_FENCE == pTrigger-pSync-type) { + SyncFence* pFence = (SyncFence*) pTrigger-pSync; + pFence-funcs.AddTrigger(pTrigger); } return Success; } -/* Below are four possible functions that can be plugged into - * pTrigger-CheckTrigger, corresponding to the four possible - * test-types. These functions are called after the counter's - * value changes but are also passed the old counter value - * so they can inspect both the old and new values. - * (PositiveTransition and NegativeTransition need to see both - * pieces of information.) These functions return the truth value - * of the trigger. +/* Below are five possible functions that can be plugged into + * pTrigger-CheckTrigger for counter sync objects, corresponding to + * the four possible test-types, and the one possible function that + * can be plugged into pTrigger-CheckTrigger for fence sync objects. + * These functions are called after the sync object's state changes + * but are also passed the old state so they can inspect both the old + * and new values. (PositiveTransition and NegativeTransition need to + * see both pieces of information.) These functions return the truth + * value of the trigger. * - * All of them include the condition pTrigger-pCounter == NULL. - * This is because the spec says that a trigger with a counter value + * All of them include the condition pTrigger-pSync == NULL. + * This is because the spec says that a trigger with a sync value * of None is always TRUE. */ @@ -250,6 +257,16 @@ SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval) XSyncValueLessOrEqual(pCounter-value, pTrigger-test_value))); } +static Bool +SyncCheckTriggerFence(SyncTrigger *pTrigger, CARD64 unused) +{ +SyncFence* pFence = (SyncFence*) pTrigger-pSync; +(void)unused; + +return (pFence == NULL || + pFence-funcs.CheckTriggered(pFence)); +} + static int SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, RESTYPE resType, Mask changes) @@ -302,30 +319,38 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, if (changes XSyncCATestType) { - if (pTrigger-test_type != XSyncPositiveTransition - pTrigger-test_type != XSyncNegativeTransition - pTrigger-test_type != XSyncPositiveComparison - pTrigger-test_type != XSyncNegativeComparison) + + if (SYNC_FENCE == pSync-type) { - client-errorValue = pTrigger-test_type; - return BadValue; + pTrigger-CheckTrigger = SyncCheckTriggerFence; } - /* select appropriate CheckTrigger function */ - - switch (pTrigger-test_type) + else { - case XSyncPositiveTransition: - pTrigger-CheckTrigger = SyncCheckTriggerPositiveTransition; - break; - case XSyncNegativeTransition: - pTrigger-CheckTrigger = SyncCheckTriggerNegativeTransition; - break; - case XSyncPositiveComparison: - pTrigger-CheckTrigger = SyncCheckTriggerPositiveComparison; - break; - case XSyncNegativeComparison: - pTrigger-CheckTrigger = SyncCheckTriggerNegativeComparison; - break; + if (pTrigger-test_type != XSyncPositiveTransition + pTrigger-test_type != XSyncNegativeTransition + pTrigger-test_type != XSyncPositiveComparison + pTrigger-test_type != XSyncNegativeComparison) + { + client-errorValue = pTrigger-test_type; + return BadValue; + } + /* select appropriate CheckTrigger function */ + + switch (pTrigger-test_type) + { + case XSyncPositiveTransition: + pTrigger-CheckTrigger = SyncCheckTriggerPositiveTransition; + break; + case XSyncNegativeTransition: + pTrigger-CheckTrigger = SyncCheckTriggerNegativeTransition; + break; + case
[PATCH xserver (v4) 08/10] Create/Destroy/Trigger/Reset/Query Fence Sync objs
Initial server side implementation of fence sync objects. Allows creation, management, and state queries of binary state objects. Currently they are not very useful as there is no way to wait for them efficiently. The basic trigger operation added here triggers relative to a given X screen's rendering operations. To perform this operation, fence sync objects must be tied to a screen. As Aaron Plattner pointed out, screens are identified but a drawable in X protocol, so a drawable argument is included in XSyncCreateFence(). The screen also could have been specified as part of the trigger operation. However, it is also desireable to associate a screen with fence sync objects at creation time so that the associated screen's driver can allocate any HW- specific resources needed by the fence object up front. Signed-off-by: James Jones jajo...@nvidia.com --- Xext/Makefile.am |3 +- Xext/sync.c | 227 +- Xext/syncsdk.h | 47 + hw/xfree86/loader/sdksyms.sh |1 + 4 files changed, 273 insertions(+), 5 deletions(-) create mode 100644 Xext/syncsdk.h diff --git a/Xext/Makefile.am b/Xext/Makefile.am index e444fd0..b6c95cb 100644 --- a/Xext/Makefile.am +++ b/Xext/Makefile.am @@ -15,7 +15,7 @@ INCLUDES = -I$(top_srcdir)/hw/xfree86/dixmods/extmod AM_CFLAGS = $(DIX_CFLAGS) if XORG -sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h +sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h syncsdk.h endif # Sources always included in libXextbuiltin.la libXext.la @@ -26,6 +26,7 @@ BUILTIN_SRCS =\ sleepuntil.c\ sleepuntil.h\ sync.c \ + syncsdk.h \ syncsrv.h \ xcmisc.c\ xtest.c diff --git a/Xext/sync.c b/Xext/sync.c index 2615c27..8955a72 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -63,10 +63,12 @@ PERFORMANCE OF THIS SOFTWARE. #include os.h #include extnsionst.h #include dixstruct.h +#include pixmapstr.h #include resource.h #include opaque.h #include X11/extensions/syncproto.h #include syncsrv.h +#include syncsdk.h #include protocol-versions.h #include stdio.h @@ -85,6 +87,7 @@ static RESTYPE RTCounter = 0; static RESTYPE RTAwait; static RESTYPE RTAlarm; static RESTYPE RTAlarmClient; +static RESTYPE RTFence; static int SyncNumSystemCounters = 0; static SyncCounter **SysCounterList = NULL; @@ -850,23 +853,34 @@ SyncCreate(ClientPtr client, XID id, unsigned char type) { SyncObject *pSync; RESTYPE resType; -unsigned long syncSize; switch (type) { case SYNC_COUNTER: resType = RTCounter; - syncSize = sizeof(SyncCounter); + pSync = malloc(sizeof(SyncCounter)); + break; +case SYNC_FENCE: + resType = RTFence; + pSync = (SyncObject *)dixAllocateObjectWithPrivates(SyncFence, + PRIVATE_SYNC_FENCE); break; default: return NULL; } -if (!(pSync = (SyncObject *)malloc(syncSize))) +if (!pSync) return NULL; if (!AddResource(id, resType, (pointer) pSync)) { - free(pSync); + switch (type) { + case SYNC_FENCE: + dixFreeObjectWithPrivates((SyncFence *)pSync, PRIVATE_SYNC_FENCE); + break; + default: + free(pSync); + } + return NULL; } @@ -1866,6 +1880,145 @@ ProcSyncDestroyAlarm(ClientPtr client) return Success; } +static int +ProcSyncCreateFence(ClientPtr client) +{ +REQUEST(xSyncCreateFenceReq); +DrawablePtr pDraw; +SyncFence *pFence; +int rc; + +REQUEST_SIZE_MATCH(xSyncCreateFenceReq); + +rc = dixLookupDrawable(pDraw, stuff-d, client, M_ANY, DixGetAttrAccess); +if (rc != Success) + return rc; + +LEGAL_NEW_RESOURCE(stuff-fid, client); + +if (!(pFence = (SyncFence *)SyncCreate(client, + stuff-fid, + SYNC_FENCE))) + return BadAlloc; + +miSyncInitFence(pDraw-pScreen, pFence, stuff-initially_triggered); + +return client-noClientException; +} + +static int +FreeFence(void *obj, XID id) +{ +SyncFence *pFence = (SyncFence *) obj; + +miSyncDestroyFence(pFence); + +return Success; +} + +int SyncVerifyFence(SyncFence **ppSyncFence, XID fid, + ClientPtr client, Mask mode) +{ +int rc = dixLookupResourceByType((pointer *)ppSyncFence, fid, RTFence, +client, mode); + +if (rc != Success) + client-errorValue = fid; + +return rc; +} + +static int +ProcSyncTriggerFence(ClientPtr client) +{ +REQUEST(xSyncTriggerFenceReq); +SyncFence *pFence; +int rc; + +REQUEST_SIZE_MATCH(xSyncTriggerFenceReq); + +rc = dixLookupResourceByType((pointer *)pFence, stuff-fid
[PATCH xserver (v4) 00/10] X Server support for Fence Sync
In v4: Completely reorganized patch basedo on Keith Packard's feedback. End result is almost identical, but the road there is very different. I've prepended a patch to add SERVER_SYNC_*_VERSION to the whole series. That this was previously missing makes the re-organization less useful, since these patches won't apply retroactively to older servers built against new protocol headers, but I've added this hoping it will help in the future. This first patch may be a candidate for back-porting to stable server branches as well. Implements X Sync Fence Objects in the server, including the damage 1.2 support for DamageSubtractAndTrigger. Re- uses X Sync Counter code wherever possible. A driver interface has also been added so DDX drivers can redirect fence sync operations to HW rendering backend operations. James Jones (10): Add and use SERVER_SYNC_*_VERSION Create SyncObject base type. Make Await SyncTrigger functions generic Factor out generic code from ProcSyncAwait() Move some sync code to miext Add fence sync driver interface Require xextproto 7.1.99 Create/Destroy/Trigger/Reset/Query Fence Sync objs Add XSyncAwaitFence() handler Expose Sync Fence Object protocol COPYING |2 +- Xext/Makefile.am |3 +- Xext/sync.c | 899 -- Xext/syncsdk.h | 47 +++ Xext/syncsrv.h | 37 +-- configure.ac | 23 +- dix/privates.c |1 + hw/xfree86/loader/sdksyms.sh |4 + include/privates.h |1 + include/protocol-versions.h |4 + miext/Makefile.am|4 +- miext/sync/Makefile.am | 14 + miext/sync/misync.c | 201 ++ miext/sync/misync.h | 77 miext/sync/misyncstr.h | 86 15 files changed, 1156 insertions(+), 247 deletions(-) create mode 100644 Xext/syncsdk.h create mode 100644 miext/sync/Makefile.am create mode 100644 miext/sync/misync.c create mode 100644 miext/sync/misync.h create mode 100644 miext/sync/misyncstr.h ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v4) 01/10] Add and use SERVER_SYNC_*_VERSION
Most extensions have a version defined in the protocol headers, and also in the server's protocol-versions.h. The latter defines which version the server advertises support for. Sync wasn't included in protocol-versions.h, and was advertising support for whatever was in the protocol headers the server was built against. Signed-off-by: James Jones jajo...@nvidia.com --- Xext/sync.c |5 +++-- include/protocol-versions.h |4 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index f23df6c..4da06ac 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -67,6 +67,7 @@ PERFORMANCE OF THIS SOFTWARE. #include opaque.h #include X11/extensions/syncproto.h #include syncsrv.h +#include protocol-versions.h #include stdio.h #if !defined(WIN32) @@ -1099,8 +1100,8 @@ ProcSyncInitialize(ClientPtr client) memset(rep, 0, sizeof(xSyncInitializeReply)); rep.type = X_Reply; rep.sequenceNumber = client-sequence; -rep.majorVersion = SYNC_MAJOR_VERSION; -rep.minorVersion = SYNC_MINOR_VERSION; +rep.majorVersion = SERVER_SYNC_MAJOR_VERSION; +rep.minorVersion = SERVER_SYNC_MINOR_VERSION; rep.length = 0; if (client-swapped) diff --git a/include/protocol-versions.h b/include/protocol-versions.h index c674465..ce28797 100644 --- a/include/protocol-versions.h +++ b/include/protocol-versions.h @@ -95,6 +95,10 @@ #define SERVER_SHM_MAJOR_VERSION 1 #define SERVER_SHM_MINOR_VERSION 1 +/* Sync */ +#define SERVER_SYNC_MAJOR_VERSION 3 +#define SERVER_SYNC_MINOR_VERSION 0 + /* Windows WM */ #define SERVER_WINDOWSWM_MAJOR_VERSION 1 #define SERVER_WINDOWSWM_MINOR_VERSION 0 -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v3) 04/10] Create SyncObject base type.
SyncObject is now the base type for SyncCounter and SyncFence. Data to be used by both types is stored in the base object. Both SyncCounter and SyncFence can be safely cast to SyncObject, and a SyncObject can be cast to the correct type based on SyncObject::type. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com Reviewed-by: Adam Jackson a...@redhat.com --- Xext/sync.c| 111 ++-- Xext/syncsrv.h | 30 ++-- 2 files changed, 87 insertions(+), 54 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 16daa63..0c6de8d 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -90,7 +90,7 @@ static int SyncNumSystemCounters = 0; static SyncCounter **SysCounterList = NULL; #define IsSystemCounter(pCounter) \ -(pCounter (pCounter-client == NULL)) +(pCounter (pCounter-sync.client == NULL)) /* these are all the alarm attributes that pertain to the alarm's trigger */ #define XSyncCAAllTrigger \ @@ -119,7 +119,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) return; pPrev = NULL; -pCur = pTrigger-pCounter-pTriglist; +pCur = pTrigger-pCounter-sync.pTriglist; while (pCur) { @@ -128,7 +128,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) if (pPrev) pPrev-next = pCur-next; else - pTrigger-pCounter-pTriglist = pCur-next; + pTrigger-pCounter-sync.pTriglist = pCur-next; free(pCur); break; @@ -152,7 +152,7 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) return Success; /* don't do anything if it's already there */ -for (pCur = pTrigger-pCounter-pTriglist; pCur; pCur = pCur-next) +for (pCur = pTrigger-pCounter-sync.pTriglist; pCur; pCur = pCur-next) { if (pCur-pTrigger == pTrigger) return Success; @@ -162,8 +162,8 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) return BadAlloc; pCur-pTrigger = pTrigger; -pCur-next = pTrigger-pCounter-pTriglist; -pTrigger-pCounter-pTriglist = pCur; +pCur-next = pTrigger-pCounter-sync.pTriglist; +pTrigger-pCounter-sync.pTriglist = pCur; if (IsSystemCounter(pTrigger-pCounter)) SyncComputeBracketValues(pTrigger-pCounter); @@ -391,14 +391,14 @@ SyncSendCounterNotifyEvents(ClientPtr client, SyncAwait **ppAwait, SyncTrigger *pTrigger = (*ppAwait)-trigger; pev-type = SyncEventBase + XSyncCounterNotify; pev-kind = XSyncCounterNotify; - pev-counter = pTrigger-pCounter-id; + pev-counter = pTrigger-pCounter-sync.id; pev-wait_value_lo = XSyncValueLow32(pTrigger-test_value); pev-wait_value_hi = XSyncValueHigh32(pTrigger-test_value); pev-counter_value_lo = XSyncValueLow32(pTrigger-pCounter-value); pev-counter_value_hi = XSyncValueHigh32(pTrigger-pCounter-value); pev-time = currentTime.milliseconds; pev-count = num_events - i - 1; /* events remaining */ - pev-destroyed = pTrigger-pCounter-beingDestroyed; + pev-destroyed = pTrigger-pCounter-sync.beingDestroyed; } /* swapping will be taken care of by this */ WriteEventsToClient(client, num_events, (xEvent *)pEvents); @@ -533,7 +533,7 @@ SyncAwaitTriggerFired(SyncTrigger *pTrigger) * always generated if the counter for one of the triggers is * destroyed. */ - if (pAwait-trigger.pCounter-beingDestroyed) + if (pAwait-trigger.pCounter-sync.beingDestroyed) { ppAwait[num_events++] = pAwait; continue; @@ -601,7 +601,7 @@ SyncChangeCounter(SyncCounter *pCounter, CARD64 newval) pCounter-value = newval; /* run through triggers to see if any become true */ -for (ptl = pCounter-pTriglist; ptl; ptl = pnext) +for (ptl = pCounter-sync.pTriglist; ptl; ptl = pnext) { pnext = ptl-next; if ((*ptl-pTrigger-CheckTrigger)(ptl-pTrigger, oldval)) @@ -693,7 +693,8 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm *pAlarm, Mask mask, XSyncCounter counter; Mask origmask = mask; -counter = pAlarm-trigger.pCounter ? pAlarm-trigger.pCounter-id : None; +counter = + pAlarm-trigger.pCounter ? pAlarm-trigger.pCounter-sync.id : None; while (mask) { @@ -782,26 +783,56 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm *pAlarm, Mask mask, return Success; } - -static SyncCounter * -SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64 initialvalue) +static SyncObject * +SyncCreate(ClientPtr client, XID id, unsigned char type) { -SyncCounter *pCounter; +SyncObject *pSync; +RESTYPE resType; +unsigned long syncSize; -if (!(pCounter = malloc(sizeof(SyncCounter +switch (type) { +case SYNC_COUNTER: + resType = RTCounter; + syncSize = sizeof
[PATCH xserver (v3) 02/10] Create/Destroy/Trigger/Reset Fence Sync objects
Initial server side implementation of fence sync objects. Allows creation and management of binary state objects. Currently they are not useful as there is no way to wait for them or query their state. The basic trigger operation added here triggers relative to a given X screen's rendering operations. To perform this operation, fence sync objects must be tied to a screen. As Aaron Plattner pointed out, screens are identified but a drawable in X protocol, so a drawable argument is included in XSyncCreateFence(). The screen also could have been specified as part of the trigger operation. However, it is also desireable to associate a screen with fence sync objects at creation time so that the associated screen's driver can allocate any HW- specific resources needed by the fence object up front. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com Reviewed-by: Adam Jackson a...@redhat.com --- Xext/sync.c| 173 Xext/syncsrv.h |6 ++ 2 files changed, 179 insertions(+), 0 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index f23df6c..147eab8 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -63,6 +63,7 @@ PERFORMANCE OF THIS SOFTWARE. #include os.h #include extnsionst.h #include dixstruct.h +#include pixmapstr.h #include resource.h #include opaque.h #include X11/extensions/syncproto.h @@ -84,6 +85,7 @@ static RESTYPE RTCounter = 0; static RESTYPE RTAwait; static RESTYPE RTAlarm; static RESTYPE RTAlarmClient; +static RESTYPE RTFence; static int SyncNumSystemCounters = 0; static SyncCounter **SysCounterList = NULL; @@ -1732,6 +1734,108 @@ ProcSyncDestroyAlarm(ClientPtr client) return Success; } +static int +ProcSyncCreateFence(ClientPtr client) +{ +REQUEST(xSyncCreateFenceReq); +DrawablePtr pDraw; +SyncFence *pFence; +int rc; + +REQUEST_SIZE_MATCH(xSyncCreateFenceReq); + +rc = dixLookupDrawable(pDraw, stuff-d, client, M_ANY, DixGetAttrAccess); +if (rc != Success) + return rc; + +LEGAL_NEW_RESOURCE(stuff-fid, client); + +if (!(pFence = malloc(sizeof(SyncFence + return BadAlloc; + +if (!AddResource(stuff-fid, RTFence, (pointer) pFence)) +{ + free(pFence); + return BadAlloc; +} + +pFence-pScreen = pDraw-pScreen; +pFence-client = client; +pFence-id = stuff-fid; +pFence-triggered = stuff-initially_triggered; + +return client-noClientException; +} + +static int +FreeFence(void *obj, XID id) +{ +SyncFence *pFence = (SyncFence *) obj; + +free(pFence); + +return Success; +} + +static int +ProcSyncTriggerFence(ClientPtr client) +{ +REQUEST(xSyncTriggerFenceReq); +SyncFence *pFence; +int rc; + +REQUEST_SIZE_MATCH(xSyncTriggerFenceReq); + +rc = dixLookupResourceByType((pointer *)pFence, stuff-fid, RTFence, +client, DixWriteAccess); +if (rc != Success) + return rc; + +pFence-triggered = TRUE; + +return client-noClientException; +} + +static int +ProcSyncResetFence(ClientPtr client) +{ +REQUEST(xSyncResetFenceReq); +SyncFence *pFence; +int rc; + +REQUEST_SIZE_MATCH(xSyncResetFenceReq); + +rc = dixLookupResourceByType((pointer *)pFence, stuff-fid, RTFence, +client, DixWriteAccess); +if (rc != Success) + return rc; + +if (pFence-triggered != TRUE) + return BadMatch; + +pFence-triggered = FALSE; + +return client-noClientException; +} + +static int +ProcSyncDestroyFence(ClientPtr client) +{ +REQUEST(xSyncDestroyFenceReq); +SyncFence *pFence; +int rc; + +REQUEST_SIZE_MATCH(xSyncDestroyFenceReq); + +rc = dixLookupResourceByType((pointer *)pFence, stuff-fid, RTFence, +client, DixDestroyAccess); +if (rc != Success) + return rc; + +FreeResource(stuff-fid, RT_NONE); +return client-noClientException; +} + /* * ** Given an extension request, call the appropriate request procedure */ @@ -1770,6 +1874,14 @@ ProcSyncDispatch(ClientPtr client) return ProcSyncSetPriority(client); case X_SyncGetPriority: return ProcSyncGetPriority(client); + case X_SyncCreateFence: + return ProcSyncCreateFence(client); + case X_SyncTriggerFence: + return ProcSyncTriggerFence(client); + case X_SyncResetFence: + return ProcSyncResetFence(client); + case X_SyncDestroyFence: + return ProcSyncDestroyFence(client); default: return BadRequest; } @@ -1969,6 +2081,57 @@ SProcSyncGetPriority(ClientPtr client) return ProcSyncGetPriority(client); } +static int +SProcSyncCreateFence(ClientPtr client) +{ +REQUEST(xSyncCreateFenceReq); +char n; + +swaps(stuff-length, n); +REQUEST_SIZE_MATCH (xSyncCreateFenceReq); +swapl(stuff-fid, n); + +return
[PATCH xserver (v3) 01/10] Require xextproto 7.1.99
Subsequent changes rely on fence sync protocol in the sync extension. This protocol is only complete in xextproto version 7.1.99 and above. Signed-off-by: James Jones jajo...@nvidia.com --- configure.ac |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index 2363e38..8211608 100644 --- a/configure.ac +++ b/configure.ac @@ -791,7 +791,7 @@ WINDOWSWMPROTO=windowswmproto APPLEWMPROTO=applewmproto = 1.4 dnl Core modules for most extensions, et al. -SDK_REQUIRED_MODULES=[xproto = 7.0.17] [randrproto = 1.2.99.3] [renderproto = 0.11] [xextproto = 7.0.99.3] [inputproto = 1.9.99.902] [kbproto = 1.0.3] fontsproto +SDK_REQUIRED_MODULES=[xproto = 7.0.17] [randrproto = 1.2.99.3] [renderproto = 0.11] [xextproto = 7.1.99] [inputproto = 1.9.99.902] [kbproto = 1.0.3] fontsproto # Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc AC_SUBST(SDK_REQUIRED_MODULES) -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v3) 00/10] X Server support for Fence Sync
Now without damage changes. Implements X Sync Fence Objects in the server, including the damage 1.2 support for DamageSubtractAndTrigger. Re- uses X Sync Counter code wherever possible. A driver interface has also been added so DDX drivers can redirect fence sync operations to HW rendering backend operations. James Jones (10): Require xextproto 7.1.99 Create/Destroy/Trigger/Reset Fence Sync objects Add XSyncQueryFence() Create SyncObject base type. Make Await SyncTrigger functions generic Generalize comment above Sync CheckTriggered funcs Add XSyncAwaitFence() handler Move some sync code to miext Add fence sync driver interface Export SyncVerifyFence() in new SDK header COPYING |2 +- Xext/Makefile.am |3 +- Xext/sync.c | 898 - Xext/syncsdk.h | 47 +++ Xext/syncsrv.h | 37 +-- configure.ac | 23 +- dix/privates.c |1 + hw/xfree86/loader/sdksyms.sh |4 + include/privates.h |1 + miext/Makefile.am|4 +- miext/sync/Makefile.am | 14 + miext/sync/misync.c | 189 + miext/sync/misync.h | 77 miext/sync/misyncstr.h | 86 14 files changed, 1141 insertions(+), 245 deletions(-) create mode 100644 Xext/syncsdk.h create mode 100644 miext/sync/Makefile.am create mode 100644 miext/sync/misync.c create mode 100644 miext/sync/misync.h create mode 100644 miext/sync/misyncstr.h ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v3) 03/10] Add XSyncQueryFence()
Allows callers to query whether or not a given fence sync object is currently triggered. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com Reviewed-by: Adam Jackson a...@redhat.com --- Xext/sync.c | 49 + 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 147eab8..16daa63 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -1836,6 +1836,38 @@ ProcSyncDestroyFence(ClientPtr client) return client-noClientException; } +static int +ProcSyncQueryFence(ClientPtr client) +{ +REQUEST(xSyncQueryFenceReq); +xSyncQueryFenceReply rep; +SyncFence *pFence; +int rc; + +REQUEST_SIZE_MATCH(xSyncQueryFenceReq); + +rc = dixLookupResourceByType((pointer *)pFence, stuff-fid, +RTFence, client, DixReadAccess); +if (rc != Success) + return rc; + +rep.type = X_Reply; +rep.length = 0; +rep.sequenceNumber = client-sequence; + +rep.triggered = pFence-triggered; + +if (client-swapped) +{ + char n; + swaps(rep.sequenceNumber, n); + swapl(rep.length, n); +} + +WriteToClient(client, sizeof(xSyncQueryFenceReply), (char *) rep); +return client-noClientException; +} + /* * ** Given an extension request, call the appropriate request procedure */ @@ -1882,6 +1914,8 @@ ProcSyncDispatch(ClientPtr client) return ProcSyncResetFence(client); case X_SyncDestroyFence: return ProcSyncDestroyFence(client); + case X_SyncQueryFence: + return ProcSyncQueryFence(client); default: return BadRequest; } @@ -2134,6 +2168,19 @@ SProcSyncDestroyFence(ClientPtr client) } static int +SProcSyncQueryFence(ClientPtr client) +{ +REQUEST(xSyncQueryFenceReq); +char n; + +swaps(stuff-length, n); +REQUEST_SIZE_MATCH (xSyncQueryFenceReq); +swapl(stuff-fid, n); + +return ProcSyncQueryFence(client); +} + +static int SProcSyncDispatch(ClientPtr client) { REQUEST(xReq); @@ -2176,6 +2223,8 @@ SProcSyncDispatch(ClientPtr client) return SProcSyncResetFence(client); case X_SyncDestroyFence: return SProcSyncDestroyFence(client); + case X_SyncQueryFence: + return SProcSyncQueryFence(client); default: return BadRequest; } -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v3) 05/10] Make Await SyncTrigger functions generic
Update all the functions dealing with Await sync triggers handle generic sync objects instead of just counters. This will facilitate code sharing between the counter sync waits and the fence sync waits. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com Reviewed-by: Adam Jackson a...@redhat.com --- Xext/sync.c| 312 +--- Xext/syncsrv.h |2 +- 2 files changed, 210 insertions(+), 104 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 0c6de8d..7cff365 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -108,18 +108,19 @@ static void SyncInitIdleTime(void); * delete and add triggers on this list. */ static void -SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) +SyncDeleteTriggerFromSyncObject(SyncTrigger *pTrigger) { SyncTriggerList *pCur; SyncTriggerList *pPrev; +SyncCounter *pCounter; -/* pCounter needs to be stored in pTrigger before calling here. */ +/* pSync needs to be stored in pTrigger before calling here. */ -if (!pTrigger-pCounter) +if (!pTrigger-pSync) return; pPrev = NULL; -pCur = pTrigger-pCounter-sync.pTriglist; +pCur = pTrigger-pSync-pTriglist; while (pCur) { @@ -128,7 +129,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) if (pPrev) pPrev-next = pCur-next; else - pTrigger-pCounter-sync.pTriglist = pCur-next; + pTrigger-pSync-pTriglist = pCur-next; free(pCur); break; @@ -138,21 +139,27 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) pCur = pCur-next; } -if (IsSystemCounter(pTrigger-pCounter)) - SyncComputeBracketValues(pTrigger-pCounter); +if (SYNC_COUNTER == pTrigger-pSync-type) +{ + pCounter = (SyncCounter *)pTrigger-pSync; + + if (IsSystemCounter(pCounter)) + SyncComputeBracketValues(pCounter); +} } static int -SyncAddTriggerToCounter(SyncTrigger *pTrigger) +SyncAddTriggerToSyncObject(SyncTrigger *pTrigger) { SyncTriggerList *pCur; +SyncCounter *pCounter; -if (!pTrigger-pCounter) +if (!pTrigger-pSync) return Success; /* don't do anything if it's already there */ -for (pCur = pTrigger-pCounter-sync.pTriglist; pCur; pCur = pCur-next) +for (pCur = pTrigger-pSync-pTriglist; pCur; pCur = pCur-next) { if (pCur-pTrigger == pTrigger) return Success; @@ -162,11 +169,16 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) return BadAlloc; pCur-pTrigger = pTrigger; -pCur-next = pTrigger-pCounter-sync.pTriglist; -pTrigger-pCounter-sync.pTriglist = pCur; +pCur-next = pTrigger-pSync-pTriglist; +pTrigger-pSync-pTriglist = pCur; -if (IsSystemCounter(pTrigger-pCounter)) - SyncComputeBracketValues(pTrigger-pCounter); +if (SYNC_COUNTER == pTrigger-pSync-type) +{ + pCounter = (SyncCounter *)pTrigger-pSync; + + if (IsSystemCounter(pCounter)) + SyncComputeBracketValues(pCounter); +} return Success; } @@ -189,69 +201,100 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) static Bool SyncCheckTriggerPositiveComparison(SyncTrigger *pTrigger, CARD64 oldval) { -return (pTrigger-pCounter == NULL || - XSyncValueGreaterOrEqual(pTrigger-pCounter-value, -pTrigger-test_value)); +SyncCounter *pCounter; + +assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +pCounter = (SyncCounter *)pTrigger-pSync; + +return (pCounter == NULL || + XSyncValueGreaterOrEqual(pCounter-value, pTrigger-test_value)); } static Bool SyncCheckTriggerNegativeComparison(SyncTrigger *pTrigger, CARD64 oldval) { -return (pTrigger-pCounter == NULL || - XSyncValueLessOrEqual(pTrigger-pCounter-value, - pTrigger-test_value)); +SyncCounter *pCounter; + +assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +pCounter = (SyncCounter *)pTrigger-pSync; + +return (pCounter == NULL || + XSyncValueLessOrEqual(pCounter-value, pTrigger-test_value)); } static Bool SyncCheckTriggerPositiveTransition(SyncTrigger *pTrigger, CARD64 oldval) { -return (pTrigger-pCounter == NULL || +SyncCounter *pCounter; + +assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +pCounter = (SyncCounter *)pTrigger-pSync; + +return (pCounter == NULL || (XSyncValueLessThan(oldval, pTrigger-test_value) -XSyncValueGreaterOrEqual(pTrigger-pCounter-value, - pTrigger-test_value))); +XSyncValueGreaterOrEqual(pCounter-value, pTrigger-test_value))); } static Bool SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval) { -return (pTrigger
[PATCH xserver (v3) 06/10] Generalize comment above Sync CheckTriggered funcs
The comment referred only to counter sync objects and did not include the new fence sync CheckTriggered function. Generalize the language so it applies to all the CheckTriggered functions. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com Reviewed-by: Adam Jackson a...@redhat.com --- Xext/sync.c | 21 +++-- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 7cff365..77ad461 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -184,17 +184,18 @@ SyncAddTriggerToSyncObject(SyncTrigger *pTrigger) } -/* Below are four possible functions that can be plugged into - * pTrigger-CheckTrigger, corresponding to the four possible - * test-types. These functions are called after the counter's - * value changes but are also passed the old counter value - * so they can inspect both the old and new values. - * (PositiveTransition and NegativeTransition need to see both - * pieces of information.) These functions return the truth value - * of the trigger. +/* Below are five possible functions that can be plugged into + * pTrigger-CheckTrigger for counter sync objects, corresponding to + * the four possible test-types, and the one possible function that + * can be plugged into pTrigger-CheckTrigger for fence sync objects. + * These functions are called after the sync object's state changes + * but are also passed the old state so they can inspect both the old + * and new values. (PositiveTransition and NegativeTransition need to + * see both pieces of information.) These functions return the truth + * value of the trigger. * - * All of them include the condition pTrigger-pCounter == NULL. - * This is because the spec says that a trigger with a counter value + * All of them include the condition pTrigger-pSync == NULL. + * This is because the spec says that a trigger with a sync value * of None is always TRUE. */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (v3) 10/10] Export SyncVerifyFence() in new SDK header
Add syncsdk.h, a new xorg SDK header. It contains SyncVerifyFence() and the helper functions that use it to look up fence sync objects. Exporting this functionality in an SDK header allows 3rd party extensions to look up fence objects in their interop APIs. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com Reviewed-by: Adam Jackson a...@redhat.com --- Xext/Makefile.am |3 +- Xext/sync.c |1 + Xext/syncsdk.h | 47 ++ Xext/syncsrv.h | 17 --- hw/xfree86/loader/sdksyms.sh |1 + 5 files changed, 51 insertions(+), 18 deletions(-) create mode 100644 Xext/syncsdk.h diff --git a/Xext/Makefile.am b/Xext/Makefile.am index e444fd0..b6c95cb 100644 --- a/Xext/Makefile.am +++ b/Xext/Makefile.am @@ -15,7 +15,7 @@ INCLUDES = -I$(top_srcdir)/hw/xfree86/dixmods/extmod AM_CFLAGS = $(DIX_CFLAGS) if XORG -sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h +sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h syncsdk.h endif # Sources always included in libXextbuiltin.la libXext.la @@ -26,6 +26,7 @@ BUILTIN_SRCS =\ sleepuntil.c\ sleepuntil.h\ sync.c \ + syncsdk.h \ syncsrv.h \ xcmisc.c\ xtest.c diff --git a/Xext/sync.c b/Xext/sync.c index 3ca4d68..1af3b03 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -68,6 +68,7 @@ PERFORMANCE OF THIS SOFTWARE. #include opaque.h #include X11/extensions/syncproto.h #include syncsrv.h +#include syncsdk.h #include stdio.h #if !defined(WIN32) diff --git a/Xext/syncsdk.h b/Xext/syncsdk.h new file mode 100644 index 000..a72c585 --- /dev/null +++ b/Xext/syncsdk.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2010 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the Software), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _SYNCSDK_H_ +#define _SYNCSDK_H_ + +#include misync.h + +extern _X_EXPORT int +SyncVerifyFence(SyncFence **ppFence, XID fid, ClientPtr client, Mask mode); + +#define VERIFY_SYNC_FENCE(pFence, fid, client, mode) \ +do { \ + int rc; \ + rc = SyncVerifyFence((pFence), (fid), (client), (mode)); \ + if (Success != rc) return rc; \ +} while (0) + +#define VERIFY_SYNC_FENCE_OR_NONE(pFence, fid, client, mode) \ +do { \ +pFence = 0;\ +if (None != fid) \ + VERIFY_SYNC_FENCE((pFence), (fid), (client), (mode)); \ +} while (0) + +#endif /* _SYNCSDK_H_ */ + diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 14d6019..7ca1fba 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -140,23 +140,6 @@ extern void SyncDestroySystemCounter( pointer pCounter ); -extern int SyncVerifyFence(SyncFence **ppFence, XID fid, - ClientPtr client, Mask mode); - -#define VERIFY_SYNC_FENCE(pFence, fid, client, mode) \ -do { \ - int rc; \ - rc = SyncVerifyFence((pFence), (fid), (client), (mode)); \ - if (Success != rc) return rc; \ -} while (0) - -#define VERIFY_SYNC_FENCE_OR_NONE(pFence, fid, client, mode) \ -do { \ -pFence = 0
[PATCH xserver (v3) 09/10] Add fence sync driver interface
-Add devPrivates to fence sync objects. -Add a X sync module screen private -Add wrappable functions to create and destroy fence sync objects -Give fence sync objects wrappable functions to trigger, test, and reset their 'triggered' value. -Give fence sync objects wrappable functions to notify driver when adding/removing triggers to/ from the sync object. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com Reviewed-by: Adam Jackson a...@redhat.com --- Xext/sync.c | 38 +++ dix/privates.c |1 + hw/xfree86/loader/sdksyms.sh |3 + include/privates.h |1 + miext/sync/misync.c | 147 +- miext/sync/misync.h | 43 - miext/sync/misyncstr.h |6 +- 7 files changed, 222 insertions(+), 17 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 9b087f6..3ca4d68 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -59,7 +59,7 @@ PERFORMANCE OF THIS SOFTWARE. #include X11/X.h #include X11/Xproto.h #include X11/Xmd.h -#include misc.h +#include scrnintstr.h #include os.h #include extnsionst.h #include dixstruct.h @@ -145,6 +145,9 @@ SyncDeleteTriggerFromSyncObject(SyncTrigger *pTrigger) if (IsSystemCounter(pCounter)) SyncComputeBracketValues(pCounter); +} else if (SYNC_FENCE == pTrigger-pSync-type) { + SyncFence* pFence = (SyncFence*) pTrigger-pSync; + pFence-funcs.DeleteTrigger(pTrigger); } } @@ -178,6 +181,9 @@ SyncAddTriggerToSyncObject(SyncTrigger *pTrigger) if (IsSystemCounter(pCounter)) SyncComputeBracketValues(pCounter); +} else if (SYNC_FENCE == pTrigger-pSync-type) { + SyncFence* pFence = (SyncFence*) pTrigger-pSync; + pFence-funcs.AddTrigger(pTrigger); } return Success; @@ -252,10 +258,11 @@ SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval) static Bool SyncCheckTriggerFence(SyncTrigger *pTrigger, CARD64 unused) { +SyncFence* pFence = (SyncFence*) pTrigger-pSync; (void)unused; -return (pTrigger-pSync == NULL || - ((SyncFence *)pTrigger-pSync)-triggered); +return (pFence == NULL || + pFence-funcs.CheckTriggered(pFence)); } static int @@ -868,22 +875,22 @@ SyncCreate(ClientPtr client, XID id, unsigned char type) { SyncObject *pSync; RESTYPE resType; -unsigned long syncSize; switch (type) { case SYNC_COUNTER: resType = RTCounter; - syncSize = sizeof(SyncCounter); + pSync = malloc(sizeof(SyncCounter)); break; case SYNC_FENCE: resType = RTFence; - syncSize = sizeof(SyncFence); + pSync = (SyncObject *)dixAllocateObjectWithPrivates(SyncFence, + PRIVATE_SYNC_FENCE); break; default: return NULL; } -if (!(pSync = (SyncObject *)malloc(syncSize))) +if (!pSync) return NULL; if (!AddResource(id, resType, (pointer) pSync)) @@ -1909,8 +1916,7 @@ ProcSyncCreateFence(ClientPtr client) SYNC_FENCE))) return BadAlloc; -pFence-pScreen = pDraw-pScreen; -pFence-triggered = stuff-initially_triggered; +miSyncInitFence(pDraw-pScreen, pFence, stuff-initially_triggered); return client-noClientException; } @@ -1930,7 +1936,9 @@ FreeFence(void *obj, XID id) free(ptl); /* destroy the trigger list as we go */ } -free(pFence); +miSyncDestroyFence(pFence); + +dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE); return Success; } @@ -1980,10 +1988,10 @@ ProcSyncResetFence(ClientPtr client) if (rc != Success) return rc; -if (pFence-triggered != TRUE) +if (pFence-funcs.CheckTriggered(pFence) != TRUE) return BadMatch; -pFence-triggered = FALSE; +pFence-funcs.Reset(pFence); return client-noClientException; } @@ -2025,7 +2033,7 @@ ProcSyncQueryFence(ClientPtr client) rep.length = 0; rep.sequenceNumber = client-sequence; -rep.triggered = pFence-triggered; +rep.triggered = pFence-funcs.CheckTriggered(pFence); if (client-swapped) { @@ -2555,6 +2563,10 @@ void SyncExtensionInit(void) { ExtensionEntry *extEntry; +ints; + +for (s = 0; s screenInfo.numScreens; s++) + miSyncSetup(screenInfo.screens[s]); if (RTCounter == 0) { diff --git a/dix/privates.c b/dix/privates.c index 687fa7a..d651258 100644 --- a/dix/privates.c +++ b/dix/privates.c @@ -447,6 +447,7 @@ static const char *key_names[PRIVATE_LAST] = { [PRIVATE_GLYPH] = GLYPH, [PRIVATE_GLYPHSET] = GLYPHSET, [PRIVATE_PICTURE] = PICTURE, +[PRIVATE_SYNC_FENCE] = SYNC_FENCE, }; void diff --git a/hw/xfree86/loader/sdksyms.sh b/hw/xfree86/loader/sdksyms.sh index
[PATCH xserver (v3) 07/10] Add XSyncAwaitFence() handler
-Add the actual ProcSyncAwaitFence() dispatch func -Factor out some more common code from ProcSyncAwait() into SyncAwaitPrologue() and SyncAwaitEpilogue(). Call these from both Await functions. -Check and handle triggers when triggering or freeing a fence sync object. -Fix a few bugs in the previous refactoring changes. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com Reviewed-by: Adam Jackson a...@redhat.com --- Xext/sync.c | 300 +++ 1 files changed, 219 insertions(+), 81 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 77ad461..aee2ca1 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -265,7 +265,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, SyncObject *pSync = pTrigger-pSync; SyncCounter *pCounter = NULL; intrc; -Bool newcounter = FALSE; +Bool newSyncObject = FALSE; if (changes XSyncCACounter) { @@ -281,7 +281,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, { /* new counter for trigger */ SyncDeleteTriggerFromSyncObject(pTrigger); pTrigger-pSync = pSync; - newcounter = TRUE; + newSyncObject = TRUE; } } @@ -310,30 +310,37 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, if (changes XSyncCATestType) { - if (pTrigger-test_type != XSyncPositiveTransition - pTrigger-test_type != XSyncNegativeTransition - pTrigger-test_type != XSyncPositiveComparison - pTrigger-test_type != XSyncNegativeComparison) + if (SYNC_FENCE == pSync-type) { - client-errorValue = pTrigger-test_type; - return BadValue; + pTrigger-CheckTrigger = SyncCheckTriggerFence; } - /* select appropriate CheckTrigger function */ - - switch (pTrigger-test_type) + else { -case XSyncPositiveTransition: - pTrigger-CheckTrigger = SyncCheckTriggerPositiveTransition; - break; -case XSyncNegativeTransition: - pTrigger-CheckTrigger = SyncCheckTriggerNegativeTransition; - break; -case XSyncPositiveComparison: - pTrigger-CheckTrigger = SyncCheckTriggerPositiveComparison; - break; -case XSyncNegativeComparison: - pTrigger-CheckTrigger = SyncCheckTriggerNegativeComparison; - break; + if (pTrigger-test_type != XSyncPositiveTransition + pTrigger-test_type != XSyncNegativeTransition + pTrigger-test_type != XSyncPositiveComparison + pTrigger-test_type != XSyncNegativeComparison) + { + client-errorValue = pTrigger-test_type; + return BadValue; + } + /* select appropriate CheckTrigger function */ + + switch (pTrigger-test_type) + { + case XSyncPositiveTransition: + pTrigger-CheckTrigger = SyncCheckTriggerPositiveTransition; + break; + case XSyncNegativeTransition: + pTrigger-CheckTrigger = SyncCheckTriggerNegativeTransition; + break; + case XSyncPositiveComparison: + pTrigger-CheckTrigger = SyncCheckTriggerPositiveComparison; + break; + case XSyncNegativeComparison: + pTrigger-CheckTrigger = SyncCheckTriggerNegativeComparison; + break; + } } } @@ -360,7 +367,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, /* we wait until we're sure there are no errors before registering * a new counter on a trigger */ -if (newcounter) +if (newSyncObject) { if ((rc = SyncAddTriggerToSyncObject(pTrigger)) != Success) return rc; @@ -607,14 +614,7 @@ SyncAwaitTriggerFired(SyncTrigger *pTrigger) continue; } - if (SYNC_FENCE == pAwait-trigger.pSync-type) - { - SyncFence *pFence = (SyncFence *) pAwait-trigger.pSync; - - if (pFence-triggered) - ppAwait[num_events++] = pAwait; - } - else if (SYNC_COUNTER == pAwait-trigger.pSync-type) + if (SYNC_COUNTER == pAwait-trigger.pSync-type) { SyncCounter *pCounter = (SyncCounter *) pAwait-trigger.pSync; @@ -654,10 +654,6 @@ SyncAwaitTriggerFired(SyncTrigger *pTrigger) ppAwait[num_events++] = pAwait; } } - else - { - FatalError(Invalid sync object type); - } } if (num_events) SyncSendCounterNotifyEvents(pAwaitUnion-header.client, ppAwait, @@ -1491,6 +1487,66 @@ ProcSyncDestroyCounter(ClientPtr client) return Success; } +static SyncAwaitUnion
[PATCH xserver (v3) 08/10] Move some sync code to miext
As a precursor to exposing fence sync objects to video drivers and other extensions, move some operations from Xext to miext/sync. Expose macros for looking up sync objects out- side of Xext/sync.c as well. Signed-off-by: James Jones jajo...@nvidia.com --- COPYING|2 +- Xext/sync.c| 27 +++ Xext/syncsrv.h | 68 +++--- configure.ac | 21 +++- miext/Makefile.am |4 +- miext/sync/Makefile.am | 14 miext/sync/misync.c| 44 + miext/sync/misync.h| 36 miext/sync/misyncstr.h | 84 9 files changed, 226 insertions(+), 74 deletions(-) create mode 100644 miext/sync/Makefile.am create mode 100644 miext/sync/misync.c create mode 100644 miext/sync/misync.h create mode 100644 miext/sync/misyncstr.h diff --git a/COPYING b/COPYING index 3fb06b8..3aad5fa 100644 --- a/COPYING +++ b/COPYING @@ -14,7 +14,7 @@ Copyright © 2006-2007 Intel Corporation Copyright © 2006 Nokia Corporation Copyright © 2006-2008 Peter Hutterer Copyright © 2006 Adam Jackson -Copyright © 2009 NVIDIA Corporation +Copyright © 2009-2010 NVIDIA Corporation Copyright © 1999 Keith Packard Copyright © 2007-2009 Red Hat, Inc. Copyright © 2005-2008 Daniel Stone diff --git a/Xext/sync.c b/Xext/sync.c index aee2ca1..9b087f6 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -1935,13 +1935,23 @@ FreeFence(void *obj, XID id) return Success; } +int SyncVerifyFence(SyncFence **ppSyncFence, XID fid, + ClientPtr client, Mask mode) +{ +int rc = dixLookupResourceByType((pointer *)ppSyncFence, fid, RTFence, +client, mode); + +if (rc != Success) + client-errorValue = fid; + +return rc; +} + static int ProcSyncTriggerFence(ClientPtr client) { REQUEST(xSyncTriggerFenceReq); SyncFence *pFence; -SyncTriggerList *ptl, *pNext; -CARD64 unused; int rc; REQUEST_SIZE_MATCH(xSyncTriggerFenceReq); @@ -1951,17 +1961,7 @@ ProcSyncTriggerFence(ClientPtr client) if (rc != Success) return rc; -pFence-triggered = TRUE; - -XSyncIntToValue(unused, 0L); - -/* run through triggers to see if any fired */ -for (ptl = pFence-sync.pTriglist; ptl; ptl = pNext) -{ - pNext = ptl-next; - if ((*ptl-pTrigger-CheckTrigger)(ptl-pTrigger, unused)) - (*ptl-pTrigger-TriggerFired)(ptl-pTrigger); -} +miSyncTriggerFence(pFence); return client-noClientException; } @@ -2548,7 +2548,6 @@ SyncResetProc(ExtensionEntry *extEntry) RTCounter = 0; } - /* * ** Initialise the extension. */ diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 99c8bf4..14d6019 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -51,31 +51,8 @@ PERFORMANCE OF THIS SOFTWARE. #ifndef _SYNCSRV_H_ #define _SYNCSRV_H_ -#define CARD64 XSyncValue /* XXX temporary! need real 64 bit values for Alpha */ - -/* Sync object types */ -#define SYNC_COUNTER 0 -#define SYNC_FENCE 1 - -typedef struct _SyncObject { -ClientPtr client; /* Owning client. 0 for system counters */ -struct _SyncTriggerList *pTriglist;/* list of triggers */ -XIDid; /* resource ID */ -unsigned char type; /* SYNC_* */ -Bool beingDestroyed; /* in process of going away */ -} SyncObject; - -typedef struct _SyncCounter { -SyncObject sync; /* Common sync object data */ -CARD64 value; /* counter value */ -struct _SysCounterInfo *pSysCounterInfo; /* NULL if not a system counter */ -} SyncCounter; - -typedef struct _SyncFence { -SyncObject sync; /* Common sync object data */ -ScreenPtr pScreen; /* Screen of this fence object */ -Bool triggered; /* fence state */ -} SyncFence; +#include misync.h +#include misyncstr.h /* * The System Counter interface @@ -107,29 +84,6 @@ typedef struct _SysCounterInfo { -typedef struct _SyncTrigger { -SyncObject *pSync; -CARD64 wait_value; /* wait value */ -unsigned int value_type; /* Absolute or Relative */ -unsigned int test_type;/* transition or Comparision type */ -CARD64 test_value; /* trigger event threshold value */ -Bool (*CheckTrigger)( - struct _SyncTrigger * /*pTrigger*/, - CARD64 /*newval*/ - ); -void (*TriggerFired)( - struct _SyncTrigger * /*pTrigger*/ - ); -void (*CounterDestroyed)( - struct _SyncTrigger * /*pTrigger*/ - ); -} SyncTrigger; - -typedef struct _SyncTriggerList
[PATCH xserver] Bump extension ABI to 5
Commit 606e079cc4d9a9db3197652ca51683c36f74efb8 moved the visual field in WindowOptRec, breaking the extension module ABI. Signed-off-by: James Jones jajo...@nvidia.com --- hw/xfree86/common/xf86Module.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/xfree86/common/xf86Module.h b/hw/xfree86/common/xf86Module.h index 72f6cf0..af7b778 100644 --- a/hw/xfree86/common/xf86Module.h +++ b/hw/xfree86/common/xf86Module.h @@ -84,7 +84,7 @@ typedef enum { #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4) #define ABI_VIDEODRV_VERSION SET_ABI_VERSION(9, 0) #define ABI_XINPUT_VERSION SET_ABI_VERSION(12, 0) -#define ABI_EXTENSION_VERSION SET_ABI_VERSION(4, 0) +#define ABI_EXTENSION_VERSION SET_ABI_VERSION(5, 0) #define ABI_FONT_VERSION SET_ABI_VERSION(0, 6) #define MODINFOSTRING1 0xef23fdc5 -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xextproto (rev4) 0/5] XSync Fence Objects
Changes since the last version: -Rebased at fd8a26edefc53b370c554a60c75ff32fc60b99c8 -Added version bump so other packages can check for fence support Adds support for binary sync objects. Objects are set to triggered using X commands that are executed relative to X rendering commands. Clients can wait for fence sync objcts to reach the triggered state using XSync APIs or using interop functionality in other APIs. This allows for efficient cross-API synchronization with X rendering operations. James Jones (5): Document changes in XSync version 3.1 Initial Fence Sync support Add XSyncQueryFence() Add protocol for XSyncAwaitFence() Bump version to 7.1.99.0 configure.ac |2 +- specs/sync.xml | 229 +-- syncconst.h|6 +- syncproto.h| 96 +++ 4 files changed, 321 insertions(+), 12 deletions(-) ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xextproto (rev4) 5/5] Bump version to 7.1.99.0
Use version 7.1.99.0 to mark the inclusion of Fence Sync protocol support. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- configure.ac |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index 599651b..41269a3 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ([2.60]) -AC_INIT([XExtProto], [7.1.2], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg]) +AC_INIT([XExtProto], [7.1.99.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xextproto (rev4) 1/5] Document changes in XSync version 3.1
Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Pierre-Loup Griffais pgriff...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- specs/sync.xml | 229 +-- 1 files changed, 220 insertions(+), 9 deletions(-) diff --git a/specs/sync.xml b/specs/sync.xml index a8064a9..e61dc17 100644 --- a/specs/sync.xml +++ b/specs/sync.xml @@ -32,6 +32,11 @@ by TeX4ht (http://www.cse.ohio-state.edu/~gurari/TeX4ht/) xhtml,docbook,html,ref surnameWiggins/surname affiliationorgnameX Consortium, Inc./orgname/affiliation /othercredit + othercredit + firstnameJames/firstname + surnameJones/surname + affiliationorgnameNVIDIA Corporation/orgname/affiliation + /othercredit /authorgroup corpnameX Consortium Standard/corpname @@ -43,8 +48,9 @@ Digital Equipment Corporation, Maynard, Massachusetts /holder /copyright copyrightyear1991/yearholderX Consortium/holder/copyright + copyrightyear2010/yearholderNVIDIA Corporation/holder/copyright - releaseinfoVersion 3.0/releaseinfo + releaseinfoVersion 3.1/releaseinfo affiliationorgnameX Consortium/orgname/affiliation productnumberX Version 11, Release 6.8/productnumber @@ -52,10 +58,10 @@ Digital Equipment Corporation, Maynard, Massachusetts para Permission to use, copy, modify, and distribute this documentation for any purpose and without fee is hereby granted, provided that the above -copyright notice appear in all copies. Olivetti, Digital, MIT, and the -X Consortium make no representations about the suitability for any purpose -of the information in this document. This documentation is provided as -is without express or implied warranty. +copyright notice appear in all copies. Olivetti, Digital, MIT, the +X Consortium, and NVIDIA make no representations about the suitability for +any purpose of the information in this document. This documentation is +provided as is without express or implied warranty. /para para @@ -133,12 +139,17 @@ frame marker. /para para -The extension adds functionCounter/function and -functionAlarm/function to the set of resources managed by the +The extension adds functionCounter/function, functionAlarm/function, +and functionFence/function to the set of resources managed by the server. A counter has a 64-bit integer value that may be increased or decreased by client requests or by the server internally. A client can block by sending an Await request that waits until one of a set of synchronization -conditions, called TRIGGERs, becomes TRUE. +conditions, called TRIGGERs, becomes TRUE. Alarms generate events when +counter values go through a specified transition. A fence has two possible +states: triggered and not triggered. Client requests can put the fence in +either of these states. A client can block until one of a set of fences +becomes triggered by sending an AwaitFence request. Fences are bound to a +particular screen at creation time. /para para @@ -168,6 +179,21 @@ clients to receive an event on a regular basis when a particular counter is changed. /para +para +The functionCreateFence/function request allows a client to create a +functionFence/function that can be triggered and reset using +functionTriggerFence/function and functionResetFence/function +requests, respectively. functionCreateFence/function takes a drawable +argument that implies which screen the fence should be created on. The +functionTriggerFence/function request changes the fence's state only +after all previous rendering commands affecting objects owned by the given +fence's screen have completed. Note that while fence objects are bound +to a screen and the simple trigger operation provided by this extension +operates at screen granularity, other extensions may add more fine-grained +trigger operations based on any number of events. The screen binding +merely establishes an upper bound for the scope of fence operations. +/para + /sect1 sect1 id=types titleTypes/title @@ -201,6 +227,7 @@ SYSTEMCOUNTER: [ ] ALARM: XID ALARMSTATE:{Active,Inactive,Destroyed} +FENCE: XID /literallayout para @@ -283,6 +310,14 @@ registry of system counter names to avoid collisions in the name space. para An ALARM is the client-side handle on an functionAlarm/function resource. /para + +para +The FENCE type defines the client-side handle on a server +functionFence/function. A fence can only be in one of two states, +represented by a BOOL. If the value is TRUE, the fence is in the triggered +state. Otherwise, the fence is in the not triggered state. +/para + /sect1 sect1 id=errors @@ -307,6 +342,15 @@ does not name a defined ALARM. /para /listitem /varlistentry + varlistentry +termFence/term +listitem + para +This error is generated if the value
[PATCH xextproto (rev4) 4/5] Add protocol for XSyncAwaitFence()
Add the fence sync object equivalent of XSyncAwait() Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- syncproto.h | 12 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/syncproto.h b/syncproto.h index 7e0a568..1453e44 100644 --- a/syncproto.h +++ b/syncproto.h @@ -72,6 +72,7 @@ PERFORMANCE OF THIS SOFTWARE. #define X_SyncResetFence 16 #define X_SyncDestroyFence17 #define X_SyncQueryFence 18 +#define X_SyncAwaitFence 19 /* cover up types from sync.h to make sure they're the right size for * protocol packaging. These will be undef'ed after all the protocol @@ -402,6 +403,17 @@ typedef struct _xSyncQueryFenceReq { } xSyncQueryFenceReq; #define sz_xSyncQueryFenceReq 8 +/* + * Wait for any of a list of fence sync objects + * to reach the triggered state. + */ +typedef struct _xSyncAwaitFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +} xSyncAwaitFenceReq; +#define sz_xSyncAwaitFenceReq 4 + typedef struct { BYTE type; CARD8 unused; -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xextproto (rev4) 3/5] Add XSyncQueryFence()
Allows callers to query whether a given fence sync object is currently triggered or not. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- syncproto.h | 28 1 files changed, 28 insertions(+), 0 deletions(-) diff --git a/syncproto.h b/syncproto.h index c38ea84..7e0a568 100644 --- a/syncproto.h +++ b/syncproto.h @@ -71,6 +71,7 @@ PERFORMANCE OF THIS SOFTWARE. #define X_SyncTriggerFence15 #define X_SyncResetFence 16 #define X_SyncDestroyFence17 +#define X_SyncQueryFence 18 /* cover up types from sync.h to make sure they're the right size for * protocol packaging. These will be undef'ed after all the protocol @@ -391,6 +392,33 @@ typedef struct _xSyncDestroyFenceReq { #define sz_xSyncDestroyFenceReq8 /* + * Query a fence object + */ +typedef struct _xSyncQueryFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +XSyncFence fid B32; +} xSyncQueryFenceReq; +#define sz_xSyncQueryFenceReq 8 + +typedef struct { +BYTE type; +CARD8 unused; +CARD16 sequenceNumber B16; +CARD32 length B32; +BOOL triggered; +BYTE pad0; +CARD16 pad1 B16; +CARD32 pad2 B32; +CARD32 pad3 B32; +CARD32 pad4 B32; +CARD32 pad5 B32; +CARD32 pad6 B32; +} xSyncQueryFenceReply; +#define sz_xSyncQueryFenceReply32 + +/* * Events */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xextproto (rev4) 2/5] Initial Fence Sync support
Defines the protocol for creation and basic management of binary state sync objects. The following operations are defined: -Creation -Destruction -Trigger -Reset Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- syncconst.h |6 -- syncproto.h | 56 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/syncconst.h b/syncconst.h index 926b60c..3acc387 100644 --- a/syncconst.h +++ b/syncconst.h @@ -54,7 +54,7 @@ PERFORMANCE OF THIS SOFTWARE. #define SYNC_NAME SYNC #define SYNC_MAJOR_VERSION 3 -#define SYNC_MINOR_VERSION 0 +#define SYNC_MINOR_VERSION 1 #define XSyncCounterNotify 0 @@ -65,7 +65,8 @@ PERFORMANCE OF THIS SOFTWARE. #define XSyncBadCounter0L #define XSyncBadAlarm 1L -#define XSyncNumberErrors (XSyncBadAlarm + 1) +#define XSyncBadFence 2L +#define XSyncNumberErrors (XSyncBadFence + 1) /* * Flags for Alarm Attributes @@ -172,6 +173,7 @@ typedef enum { typedef XID XSyncCounter; typedef XID XSyncAlarm; +typedef XID XSyncFence; typedef struct _XSyncValue { int hi; unsigned int lo; diff --git a/syncproto.h b/syncproto.h index 13b53d5..c38ea84 100644 --- a/syncproto.h +++ b/syncproto.h @@ -67,6 +67,10 @@ PERFORMANCE OF THIS SOFTWARE. #define X_SyncDestroyAlarm11 #define X_SyncSetPriority 12 #define X_SyncGetPriority 13 +#define X_SyncCreateFence 14 +#define X_SyncTriggerFence15 +#define X_SyncResetFence 16 +#define X_SyncDestroyFence17 /* cover up types from sync.h to make sure they're the right size for * protocol packaging. These will be undef'ed after all the protocol @@ -74,6 +78,8 @@ PERFORMANCE OF THIS SOFTWARE. */ #define XSyncCounter CARD32 #define XSyncAlarm CARD32 +#define XSyncFence CARD32 +#define Drawable CARD32 /* * Initialize @@ -337,6 +343,54 @@ typedef struct { #define sz_xSyncGetPriorityReply 32 /* + * Create Fence + */ +typedef struct _xSyncCreateFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +Drawable d B32; +XSyncFence fid B32; +BOOL initially_triggered; +CARD8 pad0; +CARD16 pad1; +} xSyncCreateFenceReq; +#define sz_xSyncCreateFenceReq 16 + +/* + * Put a fence object in the triggered state. + */ +typedef struct _xSyncTriggerFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +XSyncFence fid B32; +} xSyncTriggerFenceReq; +#define sz_xSyncTriggerFenceReq8 + +/* + * Put a fence in the untriggered state. + */ +typedef struct _xSyncResetFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +XSyncFence fid B32; +} xSyncResetFenceReq; +#define sz_xSyncResetFenceReq 8 + +/* + * Destroy a fence object + */ +typedef struct _xSyncDestroyFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +XSyncFence fid B32; +} xSyncDestroyFenceReq; +#define sz_xSyncDestroyFenceReq8 + +/* * Events */ @@ -373,6 +427,8 @@ typedef struct _xSyncAlarmNotifyEvent { #undef XSyncCounter #undef XSyncAlarm +#undef XSyncFence +#undef Drawable #endif /* _SYNCPROTO_H_ */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH damageproto (rev3) 1/3] Document changes in damage proto version 1.2
Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Pierre-Loup Griffais pgriff...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- damageproto.txt | 57 +- 1 files changed, 55 insertions(+), 2 deletions(-) diff --git a/damageproto.txt b/damageproto.txt index 1f254d4..59dc4ac 100644 --- a/damageproto.txt +++ b/damageproto.txt @@ -1,7 +1,7 @@ The DAMAGE Extension - Protocol Version 1.1 + Protocol Version 1.2 Document Revision 1 -2007-01-08 +2010-08-11 Keith Packard kei...@keithp.com @@ -10,6 +10,11 @@ e...@anholt.net Open Source Technology Center Intel Corporation + +James Jones +jajo...@nvidia.com +NVIDIA Corporation + 1. Introduction Monitoring the regions affected by rendering has wide-spread use, from @@ -84,6 +89,25 @@ less-incorrect rendering in this cases, the direct rendering client should translate its damage region to screen coordinates and report the damage against the root window rather than the drawable. +3.2 Additions in the 1.2 version of the protocol + +Damage is computed by the X Server during the process of generating and +submitting rendering commands to the underlying graphics hardware or +software renderer. In many cases, the actual underlying rendering will not +be completed until some indeterminate time after the damage events are +generated and received by the client. When the damage client is using out- +of-band methods to access the surfaces on which damage is reported, a method +for delaying surface accesses until after the rendering causing the damage +has landed is needed. To facilitate this, the 1.2 version of the protocol +added a request to trigger an X Synchronization Fence Object when all +rendering associated with a given damage region has been completed. Direct +rendering clients using APIs that can import X Synchronization Fence Objects +can then use API-specific methods to wait for the rendering to complete +before accessing the damaged surfaces. Specifically, this functionality is +meant to allow GLX-based direct rendering composite managers to queue +desktop updates behind a hardware barrier to avoid race conditions while +adding a minimal amount of latency. + 4. Data types The Damage object holds any accumulated damage region and reflects the @@ -97,6 +121,9 @@ Damage 6. Types + Version 1.2 relies on the XSyncFence type defined in the X + Synchronization Protocol Specification version 3.1. + DAMAGE 32-bit value (top three bits guaranteed to be zero) DamageReportLevel { DamageReportRawRectangles, @@ -220,3 +247,29 @@ DamageAdd Damage posted in this way will appear in DamageNotify events as normal, and also in server internal damage tracking (for shadow framebuffer updates, pixmap damage, and other uses). + +DamageSubtractAndTrigger + + damage: DAMAGE + repair: Region or None + parts: Region or None + finishedFence: XSyncFence or None + + damage, repair, and parts behave exactly as described above for + DamageSubtract. + + If finishedFence is not None, it is modified in the following manner: + + If repair is None: + + 1) tmp = damage + + Otherwise: + + 1) tmp = damage INTERSECT repair + + If tmp is the empty region, finishedFence will immediately be + placed in the triggered state. Otherwise, finishedFence will be + placed in the triggered state after all rendering that caused the + damage in tmp has been completed. When finishedFence reaches the + triggered state, any clients waiting on it will be unblocked. -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH damageproto (rev3) 2/3] Add XDamageSubtractAndTrigger operation
XDamageSubtractAndTrigger behaves exactly like XDamageSubtract except it receives an optional fence sync object. If the value of this object is not None, it is triggered by X once all the rendering associated with the damage regions being subtracted has completed. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- damageproto.h | 15 +++ damagewire.h |5 +++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/damageproto.h b/damageproto.h index 107e192..edc2e0a 100644 --- a/damageproto.h +++ b/damageproto.h @@ -25,6 +25,7 @@ #define _DAMAGEPROTO_H_ #include X11/Xmd.h +#include X11/extensions/syncproto.h #include X11/extensions/xfixesproto.h #include X11/extensions/damagewire.h @@ -43,6 +44,7 @@ #define Picture CARD32 #define Region CARD32 #define Damage CARD32 +#define XSyncFence CARD32 /** Version 0 **/ @@ -124,6 +126,18 @@ typedef struct { #define sz_xDamageAddReq 12 +typedef struct { +CARD8 reqType; +CARD8 damageReqType; +CARD16 length B16; +Damage damage B32; +Region repair B32; +Region parts B32; +XSyncFence finishedFence B32; +} xDamageSubtractAndTriggerReq; + +#define sz_xDamageSubtractAndTriggerReq20 + /* Events */ #define DamageNotifyMore0x80 @@ -139,6 +153,7 @@ typedef struct { xRectangle geometry; } xDamageNotifyEvent; +#undef XSyncFence #undef Damage #undef Region #undef Picture diff --git a/damagewire.h b/damagewire.h index d90a0dd..590a7bb 100644 --- a/damagewire.h +++ b/damagewire.h @@ -25,7 +25,7 @@ #defineDAMAGE_NAME DAMAGE #define DAMAGE_MAJOR 1 -#define DAMAGE_MINOR 1 +#define DAMAGE_MINOR 2 /* Version 1 / @@ -41,8 +41,9 @@ #define X_DamageDestroy2 #define X_DamageSubtract 3 #define X_DamageAdd4 +#define X_DamageSubtractAndTrigger 5 -#define XDamageNumberRequests (X_DamageAdd + 1) +#define XDamageNumberRequests (X_DamageSubtractAndTrigger + 1) /* Events */ #define XDamageNotify 0 -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH damageproto (rev3) 3/3] Bump version to 1.2.99.0
Use version 1.2.99.0 to mark the inclusion of Fence Sync protocol support. Really this should be 1.2.0, but that version was already incorrectly used. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- configure.ac |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index 60c8780..0c5b322 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ([2.60]) -AC_INIT([DamageProto], [1.2.1], +AC_INIT([DamageProto], [1.2.99.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH damageproto (rev3) 0/3] Add XDamageSubtractAndTrigger
Changes since the last version: -Added version bump so other modules can check for fence support. Adds the XDamageSubtractAndTrigger() request and bumps the damage protocol to version 1.2. Now with protocol spec updates including overview, justification, and intended usage of the new reqeust. James Jones (3): Document changes in damage proto version 1.2 Add XDamageSubtractAndTrigger operation Bump version to 1.2.99.0 configure.ac|2 +- damageproto.h | 15 ++ damageproto.txt | 57 +- damagewire.h|5 ++- 4 files changed, 74 insertions(+), 5 deletions(-) ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXext (rev3) 1/5] Backwards compat for newer XSync + older servers
Add infrastructure to make future builds of libXext that support version of XSync 3.1 compatibile with X servers exporting XSync version 3.0. As part of this, don't handle errors introduced by newer versions of the protocol than the server supports. Those error codes could be used by some other extension. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- src/XSync.c | 125 +- 1 files changed, 97 insertions(+), 28 deletions(-) diff --git a/src/XSync.c b/src/XSync.c index c21749a..99b8b2b 100644 --- a/src/XSync.c +++ b/src/XSync.c @@ -94,19 +94,103 @@ static char*sync_error_list[] = { BadAlarm, }; +typedef struct _SyncVersionInfoRec { +short major; +short minor; +int num_errors; +} SyncVersionInfo; + +static /* const */ SyncVersionInfo supported_versions[] = { +{ 3 /* major */, 0 /* minor */, 2 /* num_errors */ }, +}; + +#define NUM_VERSIONS (sizeof(supported_versions)/sizeof(supported_versions[0])) +#define GET_VERSION(info) ((info) ? (const SyncVersionInfo*)(info)-data : NULL) +#define IS_VERSION_SUPPORTED(info) (!!GET_VERSION(info)) + +static +const SyncVersionInfo* GetVersionInfo(Display *dpy) +{ +xSyncInitializeReply rep; +xSyncInitializeReq *req; +XExtCodes codes; +int i; + +if (!XQueryExtension(dpy, sync_extension_name, + codes.major_opcode, + codes.first_event, + codes.first_error)) +return NULL; + +LockDisplay(dpy); +GetReq(SyncInitialize, req); +req-reqType = codes.major_opcode; +req-syncReqType = X_SyncInitialize; +req-majorVersion = SYNC_MAJOR_VERSION; +req-minorVersion = SYNC_MINOR_VERSION; +if (!_XReply(dpy, (xReply *) rep, 0, xTrue)) +{ + UnlockDisplay(dpy); + SyncHandle(); + return NULL; +} +UnlockDisplay(dpy); +SyncHandle(); + +for (i = 0; i NUM_VERSIONS; i++) { + if (supported_versions[i].major == rep.majorVersion + supported_versions[i].minor == rep.minorVersion) { + return supported_versions[i]; + } +} + +return NULL; +} + +static +XExtDisplayInfo *find_display_create_optional(Display *dpy, Bool create) +{ +XExtDisplayInfo *dpyinfo; + +if (!sync_info) { +if (!(sync_info = XextCreateExtension())) return NULL; +} + +if (!(dpyinfo = XextFindDisplay (sync_info, dpy)) create) { +dpyinfo = XextAddDisplay(sync_info, dpy, + sync_extension_name, + sync_extension_hooks, + XSyncNumberEvents, + (XPointer)GetVersionInfo(dpy)); +} + +return dpyinfo; +} + static -XEXT_GENERATE_FIND_DISPLAY(find_display, sync_info, - sync_extension_name, - sync_extension_hooks, - XSyncNumberEvents, (XPointer) NULL) +XExtDisplayInfo *find_display (Display *dpy) +{ +return find_display_create_optional(dpy, True); +} static XEXT_GENERATE_CLOSE_DISPLAY(close_display, sync_info) static -XEXT_GENERATE_ERROR_STRING(error_string, sync_extension_name, - XSyncNumberErrors, sync_error_list) +char *error_string(Display *dpy, int code, XExtCodes *codes, char *buf, int n) +{ +XExtDisplayInfo *info = find_display_create_optional(dpy, False); +int nerr = IS_VERSION_SUPPORTED(info) ? GET_VERSION(info)-num_errors : 0; +code -= codes-first_error; +if (code = 0 code nerr) { + char tmp[256]; + sprintf (tmp, %s.%d, sync_extension_name, code); + XGetErrorDatabaseText (dpy, XProtoError, tmp, sync_error_list[code], buf, n); + return buf; +} +return (char *)0; +} static Bool wire_to_event(Display *dpy, XEvent *event, xEvent *wire) @@ -231,32 +315,17 @@ XSyncInitialize( int *major_version_return, int *minor_version_return) { XExtDisplayInfo *info = find_display(dpy); -xSyncInitializeReply rep; -xSyncInitializeReq *req; SyncCheckExtension(dpy, info, False); -LockDisplay(dpy); -GetReq(SyncInitialize, req); -req-reqType = info-codes-major_opcode; -req-syncReqType = X_SyncInitialize; -req-majorVersion = SYNC_MAJOR_VERSION; -req-minorVersion = SYNC_MINOR_VERSION; -if (!_XReply(dpy, (xReply *) rep, 0, xTrue)) -{ - UnlockDisplay(dpy); - SyncHandle(); +if (IS_VERSION_SUPPORTED(info)) { + *major_version_return = GET_VERSION(info)-major; + *minor_version_return = GET_VERSION(info)-minor; + + return True; +} else { return False; } -UnlockDisplay(dpy); -SyncHandle(); -*major_version_return = rep.majorVersion; -*minor_version_return = rep.minorVersion; -return ((rep.majorVersion == SYNC_MAJOR_VERSION) -#if SYNC_MINOR_VERSION 0 /* avoid compiler
[PATCH libXext (rev3) 0/5] XSync Fence Objects, lib portion
Changes since last version: -Rebased at d35e95fdf433a249d0293744d3e1ef6196422700 -Added xextproto version check. Adds client library support for binary sync objects added in the X Synchronization protocol version 3.1. libXext remains compatible with servers that only implement version 3.0 James Jones (5): Backwards compat for newer XSync + older servers Require xextproto = 7.1.99 Initial Fence Sync Object support Add XSyncQueryFence() Add XSyncAwaitFence() configure.ac |4 +- include/X11/extensions/sync.h | 33 + src/XSync.c | 260 - 3 files changed, 267 insertions(+), 30 deletions(-) ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXext (rev3) 2/5] Require xextproto = 7.1.99
Subsequent changes require fence sync protocol support in the XSync extension, which is only compete in version xextproto 7.1.99 and above. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- configure.ac |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 0baddc5..3aded04 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.60]) AC_INIT([libXext], -[1.2.0], +[1.2.99.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXext]) @@ -40,7 +40,7 @@ AC_PROG_LIBTOOL AC_PROG_CC # Checks for pkg-config packages -PKG_CHECK_MODULES(XEXT, [xproto = 7.0.13] [x11 = 1.1.99.1] [xextproto = 7.0.99.2]) +PKG_CHECK_MODULES(XEXT, [xproto = 7.0.13] [x11 = 1.1.99.1] [xextproto = 7.1.99]) AC_SUBST(XEXT_CFLAGS) AC_SUBST(XEXT_LIBS) -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXext (rev3) 5/5] Add XSyncAwaitFence()
Add the XSynceFence version of XSyncAwait(). Waits for fence objects to reach the triggered state. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- include/X11/extensions/sync.h |6 ++ src/XSync.c | 21 + 2 files changed, 27 insertions(+), 0 deletions(-) diff --git a/include/X11/extensions/sync.h b/include/X11/extensions/sync.h index 6a44ab9..a00d9c5 100644 --- a/include/X11/extensions/sync.h +++ b/include/X11/extensions/sync.h @@ -362,6 +362,12 @@ extern Bool XSyncQueryFence( Bool* /*triggered*/ ); +extern Bool XSyncAwaitFence( +Display* /*dpy*/, +const XSyncFence* /*fence_list*/, +int /*n_fences*/ +); + _XFUNCPROTOEND #endif /* _SYNC_SERVER */ diff --git a/src/XSync.c b/src/XSync.c index ca9a67c..2bdecfc 100644 --- a/src/XSync.c +++ b/src/XSync.c @@ -874,6 +874,27 @@ XSyncQueryFence(Display *dpy, XSyncFence fence, Bool *triggered) return True; } +Bool +XSyncAwaitFence(Display *dpy, const XSyncFence *fence_list, int n_fences) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncAwaitFenceReq *req; + +SyncCheckExtension(dpy, info, False); + +LockDisplay(dpy); +GetReq(SyncAwaitFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncAwaitFence; +SetReqLen(req, n_fences, n_fences); + +Data32(dpy, (char *)fence_list, sizeof(CARD32) * n_fences); + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + /* * Functions corresponding to the macros for manipulating 64-bit values */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXext (rev3) 3/5] Initial Fence Sync Object support
Allows creating and managing binary state sync objects. Currently they aren't useful because there is not yet a way to wait for them or query their state. X fence objects are owned by a screen. As Aaron Plattner pointed out, screens are identified by a drawable in X protocol, so XSyncCreateFence() takes a drawable to identify which screen to create the fence on. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- include/X11/extensions/sync.h | 21 ++ src/XSync.c | 85 + 2 files changed, 106 insertions(+), 0 deletions(-) diff --git a/include/X11/extensions/sync.h b/include/X11/extensions/sync.h index af49c37..7f4b5c5 100644 --- a/include/X11/extensions/sync.h +++ b/include/X11/extensions/sync.h @@ -335,6 +335,27 @@ extern Status XSyncGetPriority( int* /*return_priority*/ ); +extern XSyncFence XSyncCreateFence( +Display* /*dpy*/, +Drawable /*d*/, +Bool /*initially_triggered*/ +); + +extern Bool XSyncTriggerFence( +Display* /*dpy*/, +XSyncFence /*fence*/ +); + +extern Bool XSyncResetFence( +Display* /*dpy*/, +XSyncFence /*fence*/ +); + +extern Bool XSyncDestroyFence( +Display* /*dpy*/, +XSyncFence /*fence*/ +); + _XFUNCPROTOEND #endif /* _SYNC_SERVER */ diff --git a/src/XSync.c b/src/XSync.c index 99b8b2b..5236b40 100644 --- a/src/XSync.c +++ b/src/XSync.c @@ -92,6 +92,7 @@ static XExtensionHooks sync_extension_hooks = { static char*sync_error_list[] = { BadCounter, BadAlarm, +BadFence, }; typedef struct _SyncVersionInfoRec { @@ -102,6 +103,7 @@ typedef struct _SyncVersionInfoRec { static /* const */ SyncVersionInfo supported_versions[] = { { 3 /* major */, 0 /* minor */, 2 /* num_errors */ }, +{ 3 /* major */, 1 /* minor */, 3 /* num_errors */ }, }; #define NUM_VERSIONS (sizeof(supported_versions)/sizeof(supported_versions[0])) @@ -760,6 +762,89 @@ XSyncGetPriority(Display *dpy, XID client_resource_id, int *return_priority) return True; } +XSyncFence +XSyncCreateFence(Display *dpy, Drawable d, Bool initially_triggered) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncCreateFenceReq *req; +XSyncFence id; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncCreateFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncCreateFence; + +req-d = d; +id = req-fid = XAllocID(dpy); +req-initially_triggered = initially_triggered; + +UnlockDisplay(dpy); +SyncHandle(); +return id; +} + +Bool +XSyncTriggerFence(Display *dpy, XSyncFence fence) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncTriggerFenceReq *req; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncTriggerFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncTriggerFence; + +req-fid = fence; + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + +Bool +XSyncResetFence(Display *dpy, XSyncFence fence) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncResetFenceReq *req; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncResetFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncResetFence; + +req-fid = fence; + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + +Bool +XSyncDestroyFence(Display *dpy, XSyncFence fence) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncDestroyFenceReq *req; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncDestroyFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncDestroyFence; + +req-fid = fence; + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + /* * Functions corresponding to the macros for manipulating 64-bit values */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXext (rev3) 4/5] Add XSyncQueryFence()
Allows callers to query whether or not a given fence sync object is currently triggered. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- include/X11/extensions/sync.h |6 ++ src/XSync.c | 29 + 2 files changed, 35 insertions(+), 0 deletions(-) diff --git a/include/X11/extensions/sync.h b/include/X11/extensions/sync.h index 7f4b5c5..6a44ab9 100644 --- a/include/X11/extensions/sync.h +++ b/include/X11/extensions/sync.h @@ -356,6 +356,12 @@ extern Bool XSyncDestroyFence( XSyncFence /*fence*/ ); +extern Bool XSyncQueryFence( +Display* /*dpy*/, +XSyncFence /*fence*/, +Bool* /*triggered*/ +); + _XFUNCPROTOEND #endif /* _SYNC_SERVER */ diff --git a/src/XSync.c b/src/XSync.c index 5236b40..ca9a67c 100644 --- a/src/XSync.c +++ b/src/XSync.c @@ -845,6 +845,35 @@ XSyncDestroyFence(Display *dpy, XSyncFence fence) return True; } +Bool +XSyncQueryFence(Display *dpy, XSyncFence fence, Bool *triggered) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncQueryFenceReply rep; +xSyncQueryFenceReq *req; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncQueryFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncQueryFence; +req-fid = fence; + +if (!_XReply(dpy, (xReply *) rep, 0, xFalse)) +{ + UnlockDisplay(dpy); + SyncHandle(); + return False; +} +if (triggered) + *triggered = rep.triggered; + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + /* * Functions corresponding to the macros for manipulating 64-bit values */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXdamage (rev2)] Add XDamageSubtractAndTrigger operation
Changes since last version of patch: -Add damageproto and xextproto version checks. XDamageSubtractAndTrigger behaves exactly like XDamageSubtract except it receives an optional fence sync object. If the value of this object is not None, it is triggered by X once all the rendering associated with the damage regions being subtracted has completed. Bump version number to match protocol version, and require damageproto 1.2.99 Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- configure.ac |4 ++-- include/X11/extensions/Xdamage.h |7 +++ src/Makefile.am |2 +- src/Xdamage.c| 21 + 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 9382ec5..b199a78 100644 --- a/configure.ac +++ b/configure.ac @@ -31,7 +31,7 @@ dnl digit in the version number to track changes which don't affect the dnl protocol, so Xdamage version l.n.m corresponds to protocol version l.n dnl AC_INIT(libXdamage, - 1.1.3, + 1.2.0, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libXdamage) AM_INIT_AUTOMAKE([foreign dist-bzip2]) @@ -53,7 +53,7 @@ AC_PROG_LIBTOOL DAMAGEEXT_VERSION=[`echo $VERSION | sed 's/^\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/'`] AC_SUBST(DAMAGEEXT_VERSION) -PKG_CHECK_MODULES(XDAMAGE, [damageproto = $DAMAGEEXT_VERSION] xfixes fixesproto xextproto x11) +PKG_CHECK_MODULES(XDAMAGE, [damageproto = 1.2.99] xfixes fixesproto [xextproto = 7.1.99] x11) AC_SUBST(XDAMAGE_CFLAGS) AC_OUTPUT([Makefile diff --git a/include/X11/extensions/Xdamage.h b/include/X11/extensions/Xdamage.h index 5ecf035..181601d 100644 --- a/include/X11/extensions/Xdamage.h +++ b/include/X11/extensions/Xdamage.h @@ -25,9 +25,11 @@ #include X11/extensions/damagewire.h #include X11/extensions/Xfixes.h +#include X11/extensions/syncconst.h #include X11/Xfuncproto.h #define XDAMAGE_1_1_INTERFACE +#define XDAMAGE_1_2_INTERFACE typedef XID Damage; @@ -68,6 +70,11 @@ XDamageSubtract (Display *dpy, Damage damage, void XDamageAdd (Display *dpy, Drawable drawable, XserverRegion region); +void +XDamageSubtractAndTrigger (Display *dpy, Damage damage, + XserverRegion repair, XserverRegion parts, + XSyncFence finishedFence); + _XFUNCPROTOEND #endif /* _XDAMAGE_H_ */ diff --git a/src/Makefile.am b/src/Makefile.am index 787fc04..f0564f4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ AM_CFLAGS = $(CWARNFLAGS) $(XDAMAGE_CFLAGS) INCLUDES = -I$(top_srcdir)/include/X11/extensions -libXdamage_la_LDFLAGS = -version-number 1:1:0 -no-undefined +libXdamage_la_LDFLAGS = -version-number 1:2:0 -no-undefined libXdamageincludedir = $(includedir)/X11/extensions libXdamageinclude_HEADERS = $(top_srcdir)/include/X11/extensions/Xdamage.h diff --git a/src/Xdamage.c b/src/Xdamage.c index 3a368d2..636ab48 100644 --- a/src/Xdamage.c +++ b/src/Xdamage.c @@ -383,3 +383,24 @@ XDamageAdd (Display *dpy, Drawable drawable, XserverRegion region) UnlockDisplay (dpy); SyncHandle (); } + +void +XDamageSubtractAndTrigger (Display *dpy, Damage damage, + XserverRegion repair, XserverRegion parts, + XSyncFence finishedFence) +{ +XDamageExtDisplayInfo *info = XDamageFindDisplay (dpy); +xDamageSubtractAndTriggerReq *req; + +XDamageSimpleCheckExtension (dpy, info); +LockDisplay (dpy); +GetReq (DamageSubtractAndTrigger, req); +req-reqType = info-codes-major_opcode; +req-damageReqType = X_DamageSubtractAndTrigger; +req-damage = damage; +req-repair = repair; +req-parts = parts; +req-finishedFence = finishedFence; +UnlockDisplay (dpy); +SyncHandle (); +} -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH damageproto (rev4) 0/3] Add XDamageSubtractAndTrigger
Changes since the last version: -Changed new version from 1.2.99 - 1.3.0 Adds the XDamageSubtractAndTrigger() request and bumps the damage protocol to version 1.2. Now with protocol spec updates including overview, justification, and intended usage of the new reqeust. James Jones (3): Document changes in damage proto version 1.2 Add XDamageSubtractAndTrigger operation Bump version to 1.3.0 configure.ac|2 +- damageproto.h | 15 ++ damageproto.txt | 57 +- damagewire.h|5 ++- 4 files changed, 74 insertions(+), 5 deletions(-) ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH damageproto (rev4) 3/3] Bump version to 1.3.0
Use version 1.3.0 to mark the inclusion of Fence Sync protocol support. Really this should be 1.2.0, but that version was already incorrectly used. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- configure.ac |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index 60c8780..5e05fdd 100644 --- a/configure.ac +++ b/configure.ac @@ -22,7 +22,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ([2.60]) -AC_INIT([DamageProto], [1.2.1], +AC_INIT([DamageProto], [1.3.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg]) AM_INIT_AUTOMAKE([foreign dist-bzip2]) AM_MAINTAINER_MODE -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH damageproto (rev4) 2/3] Add XDamageSubtractAndTrigger operation
XDamageSubtractAndTrigger behaves exactly like XDamageSubtract except it receives an optional fence sync object. If the value of this object is not None, it is triggered by X once all the rendering associated with the damage regions being subtracted has completed. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- damageproto.h | 15 +++ damagewire.h |5 +++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/damageproto.h b/damageproto.h index 107e192..edc2e0a 100644 --- a/damageproto.h +++ b/damageproto.h @@ -25,6 +25,7 @@ #define _DAMAGEPROTO_H_ #include X11/Xmd.h +#include X11/extensions/syncproto.h #include X11/extensions/xfixesproto.h #include X11/extensions/damagewire.h @@ -43,6 +44,7 @@ #define Picture CARD32 #define Region CARD32 #define Damage CARD32 +#define XSyncFence CARD32 /** Version 0 **/ @@ -124,6 +126,18 @@ typedef struct { #define sz_xDamageAddReq 12 +typedef struct { +CARD8 reqType; +CARD8 damageReqType; +CARD16 length B16; +Damage damage B32; +Region repair B32; +Region parts B32; +XSyncFence finishedFence B32; +} xDamageSubtractAndTriggerReq; + +#define sz_xDamageSubtractAndTriggerReq20 + /* Events */ #define DamageNotifyMore0x80 @@ -139,6 +153,7 @@ typedef struct { xRectangle geometry; } xDamageNotifyEvent; +#undef XSyncFence #undef Damage #undef Region #undef Picture diff --git a/damagewire.h b/damagewire.h index d90a0dd..590a7bb 100644 --- a/damagewire.h +++ b/damagewire.h @@ -25,7 +25,7 @@ #defineDAMAGE_NAME DAMAGE #define DAMAGE_MAJOR 1 -#define DAMAGE_MINOR 1 +#define DAMAGE_MINOR 2 /* Version 1 / @@ -41,8 +41,9 @@ #define X_DamageDestroy2 #define X_DamageSubtract 3 #define X_DamageAdd4 +#define X_DamageSubtractAndTrigger 5 -#define XDamageNumberRequests (X_DamageAdd + 1) +#define XDamageNumberRequests (X_DamageSubtractAndTrigger + 1) /* Events */ #define XDamageNotify 0 -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH damageproto (rev4) 1/3] Document changes in damage proto version 1.2
Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Pierre-Loup Griffais pgriff...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- damageproto.txt | 57 +- 1 files changed, 55 insertions(+), 2 deletions(-) diff --git a/damageproto.txt b/damageproto.txt index 1f254d4..59dc4ac 100644 --- a/damageproto.txt +++ b/damageproto.txt @@ -1,7 +1,7 @@ The DAMAGE Extension - Protocol Version 1.1 + Protocol Version 1.2 Document Revision 1 -2007-01-08 +2010-08-11 Keith Packard kei...@keithp.com @@ -10,6 +10,11 @@ e...@anholt.net Open Source Technology Center Intel Corporation + +James Jones +jajo...@nvidia.com +NVIDIA Corporation + 1. Introduction Monitoring the regions affected by rendering has wide-spread use, from @@ -84,6 +89,25 @@ less-incorrect rendering in this cases, the direct rendering client should translate its damage region to screen coordinates and report the damage against the root window rather than the drawable. +3.2 Additions in the 1.2 version of the protocol + +Damage is computed by the X Server during the process of generating and +submitting rendering commands to the underlying graphics hardware or +software renderer. In many cases, the actual underlying rendering will not +be completed until some indeterminate time after the damage events are +generated and received by the client. When the damage client is using out- +of-band methods to access the surfaces on which damage is reported, a method +for delaying surface accesses until after the rendering causing the damage +has landed is needed. To facilitate this, the 1.2 version of the protocol +added a request to trigger an X Synchronization Fence Object when all +rendering associated with a given damage region has been completed. Direct +rendering clients using APIs that can import X Synchronization Fence Objects +can then use API-specific methods to wait for the rendering to complete +before accessing the damaged surfaces. Specifically, this functionality is +meant to allow GLX-based direct rendering composite managers to queue +desktop updates behind a hardware barrier to avoid race conditions while +adding a minimal amount of latency. + 4. Data types The Damage object holds any accumulated damage region and reflects the @@ -97,6 +121,9 @@ Damage 6. Types + Version 1.2 relies on the XSyncFence type defined in the X + Synchronization Protocol Specification version 3.1. + DAMAGE 32-bit value (top three bits guaranteed to be zero) DamageReportLevel { DamageReportRawRectangles, @@ -220,3 +247,29 @@ DamageAdd Damage posted in this way will appear in DamageNotify events as normal, and also in server internal damage tracking (for shadow framebuffer updates, pixmap damage, and other uses). + +DamageSubtractAndTrigger + + damage: DAMAGE + repair: Region or None + parts: Region or None + finishedFence: XSyncFence or None + + damage, repair, and parts behave exactly as described above for + DamageSubtract. + + If finishedFence is not None, it is modified in the following manner: + + If repair is None: + + 1) tmp = damage + + Otherwise: + + 1) tmp = damage INTERSECT repair + + If tmp is the empty region, finishedFence will immediately be + placed in the triggered state. Otherwise, finishedFence will be + placed in the triggered state after all rendering that caused the + damage in tmp has been completed. When finishedFence reaches the + triggered state, any clients waiting on it will be unblocked. -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (rev2) 5/9] Generalize comment above Sync CheckTriggered funcs
The comment referred only to counter sync objects and did not include the new fence sync CheckTriggered function. Generalize the language so it applies to all the CheckTriggered functions. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- Xext/sync.c | 21 +++-- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 7cff365..77ad461 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -184,17 +184,18 @@ SyncAddTriggerToSyncObject(SyncTrigger *pTrigger) } -/* Below are four possible functions that can be plugged into - * pTrigger-CheckTrigger, corresponding to the four possible - * test-types. These functions are called after the counter's - * value changes but are also passed the old counter value - * so they can inspect both the old and new values. - * (PositiveTransition and NegativeTransition need to see both - * pieces of information.) These functions return the truth value - * of the trigger. +/* Below are five possible functions that can be plugged into + * pTrigger-CheckTrigger for counter sync objects, corresponding to + * the four possible test-types, and the one possible function that + * can be plugged into pTrigger-CheckTrigger for fence sync objects. + * These functions are called after the sync object's state changes + * but are also passed the old state so they can inspect both the old + * and new values. (PositiveTransition and NegativeTransition need to + * see both pieces of information.) These functions return the truth + * value of the trigger. * - * All of them include the condition pTrigger-pCounter == NULL. - * This is because the spec says that a trigger with a counter value + * All of them include the condition pTrigger-pSync == NULL. + * This is because the spec says that a trigger with a sync value * of None is always TRUE. */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (rev2) 3/9] Create SyncObject base type.
SyncObject is now the base type for SyncCounter and SyncFence. Data to be used by both types is stored in the base object. Both SyncCounter and SyncFence can be safely cast to SyncObject, and a SyncObject can be cast to the correct type based on SyncObject::type. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- Xext/sync.c| 111 ++-- Xext/syncsrv.h | 30 ++-- 2 files changed, 87 insertions(+), 54 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 16daa63..0c6de8d 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -90,7 +90,7 @@ static int SyncNumSystemCounters = 0; static SyncCounter **SysCounterList = NULL; #define IsSystemCounter(pCounter) \ -(pCounter (pCounter-client == NULL)) +(pCounter (pCounter-sync.client == NULL)) /* these are all the alarm attributes that pertain to the alarm's trigger */ #define XSyncCAAllTrigger \ @@ -119,7 +119,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) return; pPrev = NULL; -pCur = pTrigger-pCounter-pTriglist; +pCur = pTrigger-pCounter-sync.pTriglist; while (pCur) { @@ -128,7 +128,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) if (pPrev) pPrev-next = pCur-next; else - pTrigger-pCounter-pTriglist = pCur-next; + pTrigger-pCounter-sync.pTriglist = pCur-next; free(pCur); break; @@ -152,7 +152,7 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) return Success; /* don't do anything if it's already there */ -for (pCur = pTrigger-pCounter-pTriglist; pCur; pCur = pCur-next) +for (pCur = pTrigger-pCounter-sync.pTriglist; pCur; pCur = pCur-next) { if (pCur-pTrigger == pTrigger) return Success; @@ -162,8 +162,8 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) return BadAlloc; pCur-pTrigger = pTrigger; -pCur-next = pTrigger-pCounter-pTriglist; -pTrigger-pCounter-pTriglist = pCur; +pCur-next = pTrigger-pCounter-sync.pTriglist; +pTrigger-pCounter-sync.pTriglist = pCur; if (IsSystemCounter(pTrigger-pCounter)) SyncComputeBracketValues(pTrigger-pCounter); @@ -391,14 +391,14 @@ SyncSendCounterNotifyEvents(ClientPtr client, SyncAwait **ppAwait, SyncTrigger *pTrigger = (*ppAwait)-trigger; pev-type = SyncEventBase + XSyncCounterNotify; pev-kind = XSyncCounterNotify; - pev-counter = pTrigger-pCounter-id; + pev-counter = pTrigger-pCounter-sync.id; pev-wait_value_lo = XSyncValueLow32(pTrigger-test_value); pev-wait_value_hi = XSyncValueHigh32(pTrigger-test_value); pev-counter_value_lo = XSyncValueLow32(pTrigger-pCounter-value); pev-counter_value_hi = XSyncValueHigh32(pTrigger-pCounter-value); pev-time = currentTime.milliseconds; pev-count = num_events - i - 1; /* events remaining */ - pev-destroyed = pTrigger-pCounter-beingDestroyed; + pev-destroyed = pTrigger-pCounter-sync.beingDestroyed; } /* swapping will be taken care of by this */ WriteEventsToClient(client, num_events, (xEvent *)pEvents); @@ -533,7 +533,7 @@ SyncAwaitTriggerFired(SyncTrigger *pTrigger) * always generated if the counter for one of the triggers is * destroyed. */ - if (pAwait-trigger.pCounter-beingDestroyed) + if (pAwait-trigger.pCounter-sync.beingDestroyed) { ppAwait[num_events++] = pAwait; continue; @@ -601,7 +601,7 @@ SyncChangeCounter(SyncCounter *pCounter, CARD64 newval) pCounter-value = newval; /* run through triggers to see if any become true */ -for (ptl = pCounter-pTriglist; ptl; ptl = pnext) +for (ptl = pCounter-sync.pTriglist; ptl; ptl = pnext) { pnext = ptl-next; if ((*ptl-pTrigger-CheckTrigger)(ptl-pTrigger, oldval)) @@ -693,7 +693,8 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm *pAlarm, Mask mask, XSyncCounter counter; Mask origmask = mask; -counter = pAlarm-trigger.pCounter ? pAlarm-trigger.pCounter-id : None; +counter = + pAlarm-trigger.pCounter ? pAlarm-trigger.pCounter-sync.id : None; while (mask) { @@ -782,26 +783,56 @@ SyncChangeAlarmAttributes(ClientPtr client, SyncAlarm *pAlarm, Mask mask, return Success; } - -static SyncCounter * -SyncCreateCounter(ClientPtr client, XSyncCounter id, CARD64 initialvalue) +static SyncObject * +SyncCreate(ClientPtr client, XID id, unsigned char type) { -SyncCounter *pCounter; +SyncObject *pSync; +RESTYPE resType; +unsigned long syncSize; -if (!(pCounter = malloc(sizeof(SyncCounter +switch (type) { +case SYNC_COUNTER: + resType = RTCounter; + syncSize = sizeof(SyncCounter); + break; +case SYNC_FENCE
[PATCH xserver (rev2) 2/9] Add XSyncQueryFence()
Allows callers to query whether or not a given fence sync object is currently triggered. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- Xext/sync.c | 49 + 1 files changed, 49 insertions(+), 0 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 147eab8..16daa63 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -1836,6 +1836,38 @@ ProcSyncDestroyFence(ClientPtr client) return client-noClientException; } +static int +ProcSyncQueryFence(ClientPtr client) +{ +REQUEST(xSyncQueryFenceReq); +xSyncQueryFenceReply rep; +SyncFence *pFence; +int rc; + +REQUEST_SIZE_MATCH(xSyncQueryFenceReq); + +rc = dixLookupResourceByType((pointer *)pFence, stuff-fid, +RTFence, client, DixReadAccess); +if (rc != Success) + return rc; + +rep.type = X_Reply; +rep.length = 0; +rep.sequenceNumber = client-sequence; + +rep.triggered = pFence-triggered; + +if (client-swapped) +{ + char n; + swaps(rep.sequenceNumber, n); + swapl(rep.length, n); +} + +WriteToClient(client, sizeof(xSyncQueryFenceReply), (char *) rep); +return client-noClientException; +} + /* * ** Given an extension request, call the appropriate request procedure */ @@ -1882,6 +1914,8 @@ ProcSyncDispatch(ClientPtr client) return ProcSyncResetFence(client); case X_SyncDestroyFence: return ProcSyncDestroyFence(client); + case X_SyncQueryFence: + return ProcSyncQueryFence(client); default: return BadRequest; } @@ -2134,6 +2168,19 @@ SProcSyncDestroyFence(ClientPtr client) } static int +SProcSyncQueryFence(ClientPtr client) +{ +REQUEST(xSyncQueryFenceReq); +char n; + +swaps(stuff-length, n); +REQUEST_SIZE_MATCH (xSyncQueryFenceReq); +swapl(stuff-fid, n); + +return ProcSyncQueryFence(client); +} + +static int SProcSyncDispatch(ClientPtr client) { REQUEST(xReq); @@ -2176,6 +2223,8 @@ SProcSyncDispatch(ClientPtr client) return SProcSyncResetFence(client); case X_SyncDestroyFence: return SProcSyncDestroyFence(client); + case X_SyncQueryFence: + return SProcSyncQueryFence(client); default: return BadRequest; } -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver (rev2) 8/9] Add fence sync driver interface
-Add devPrivates to fence sync objects. -Add a X sync module screen private -Add wrappable functions to create and destroy fence sync objects -Give fence sync objects wrappable functions to trigger, test, and reset their 'triggered' value. -Give fence sync objects wrappable functions to notify driver when adding/removing triggers to/ from the sync object. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- Xext/sync.c | 38 +++ dix/privates.c |1 + hw/xfree86/loader/sdksyms.sh |3 + include/privates.h |1 + miext/sync/misync.c | 147 +- miext/sync/misync.h | 43 - miext/sync/misyncstr.h |6 +- 7 files changed, 222 insertions(+), 17 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 9b087f6..3ca4d68 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -59,7 +59,7 @@ PERFORMANCE OF THIS SOFTWARE. #include X11/X.h #include X11/Xproto.h #include X11/Xmd.h -#include misc.h +#include scrnintstr.h #include os.h #include extnsionst.h #include dixstruct.h @@ -145,6 +145,9 @@ SyncDeleteTriggerFromSyncObject(SyncTrigger *pTrigger) if (IsSystemCounter(pCounter)) SyncComputeBracketValues(pCounter); +} else if (SYNC_FENCE == pTrigger-pSync-type) { + SyncFence* pFence = (SyncFence*) pTrigger-pSync; + pFence-funcs.DeleteTrigger(pTrigger); } } @@ -178,6 +181,9 @@ SyncAddTriggerToSyncObject(SyncTrigger *pTrigger) if (IsSystemCounter(pCounter)) SyncComputeBracketValues(pCounter); +} else if (SYNC_FENCE == pTrigger-pSync-type) { + SyncFence* pFence = (SyncFence*) pTrigger-pSync; + pFence-funcs.AddTrigger(pTrigger); } return Success; @@ -252,10 +258,11 @@ SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval) static Bool SyncCheckTriggerFence(SyncTrigger *pTrigger, CARD64 unused) { +SyncFence* pFence = (SyncFence*) pTrigger-pSync; (void)unused; -return (pTrigger-pSync == NULL || - ((SyncFence *)pTrigger-pSync)-triggered); +return (pFence == NULL || + pFence-funcs.CheckTriggered(pFence)); } static int @@ -868,22 +875,22 @@ SyncCreate(ClientPtr client, XID id, unsigned char type) { SyncObject *pSync; RESTYPE resType; -unsigned long syncSize; switch (type) { case SYNC_COUNTER: resType = RTCounter; - syncSize = sizeof(SyncCounter); + pSync = malloc(sizeof(SyncCounter)); break; case SYNC_FENCE: resType = RTFence; - syncSize = sizeof(SyncFence); + pSync = (SyncObject *)dixAllocateObjectWithPrivates(SyncFence, + PRIVATE_SYNC_FENCE); break; default: return NULL; } -if (!(pSync = (SyncObject *)malloc(syncSize))) +if (!pSync) return NULL; if (!AddResource(id, resType, (pointer) pSync)) @@ -1909,8 +1916,7 @@ ProcSyncCreateFence(ClientPtr client) SYNC_FENCE))) return BadAlloc; -pFence-pScreen = pDraw-pScreen; -pFence-triggered = stuff-initially_triggered; +miSyncInitFence(pDraw-pScreen, pFence, stuff-initially_triggered); return client-noClientException; } @@ -1930,7 +1936,9 @@ FreeFence(void *obj, XID id) free(ptl); /* destroy the trigger list as we go */ } -free(pFence); +miSyncDestroyFence(pFence); + +dixFreeObjectWithPrivates(pFence, PRIVATE_SYNC_FENCE); return Success; } @@ -1980,10 +1988,10 @@ ProcSyncResetFence(ClientPtr client) if (rc != Success) return rc; -if (pFence-triggered != TRUE) +if (pFence-funcs.CheckTriggered(pFence) != TRUE) return BadMatch; -pFence-triggered = FALSE; +pFence-funcs.Reset(pFence); return client-noClientException; } @@ -2025,7 +2033,7 @@ ProcSyncQueryFence(ClientPtr client) rep.length = 0; rep.sequenceNumber = client-sequence; -rep.triggered = pFence-triggered; +rep.triggered = pFence-funcs.CheckTriggered(pFence); if (client-swapped) { @@ -2555,6 +2563,10 @@ void SyncExtensionInit(void) { ExtensionEntry *extEntry; +ints; + +for (s = 0; s screenInfo.numScreens; s++) + miSyncSetup(screenInfo.screens[s]); if (RTCounter == 0) { diff --git a/dix/privates.c b/dix/privates.c index 687fa7a..d651258 100644 --- a/dix/privates.c +++ b/dix/privates.c @@ -447,6 +447,7 @@ static const char *key_names[PRIVATE_LAST] = { [PRIVATE_GLYPH] = GLYPH, [PRIVATE_GLYPHSET] = GLYPHSET, [PRIVATE_PICTURE] = PICTURE, +[PRIVATE_SYNC_FENCE] = SYNC_FENCE, }; void diff --git a/hw/xfree86/loader/sdksyms.sh b/hw/xfree86/loader/sdksyms.sh index 6ca368e..ac3e59b 100755 --- a/hw/xfree86/loader
[PATCH xserver (rev2) 6/9] Add XSyncAwaitFence() handler
-Add the actual ProcSyncAwaitFence() dispatch func -Factor out some more common code from ProcSyncAwait() into SyncAwaitPrologue() and SyncAwaitEpilogue(). Call these from both Await functions. -Check and handle triggers when triggering or freeing a fence sync object. -Fix a few bugs in the previous refactoring changes. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- Xext/sync.c | 300 +++ 1 files changed, 219 insertions(+), 81 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 77ad461..aee2ca1 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -265,7 +265,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, SyncObject *pSync = pTrigger-pSync; SyncCounter *pCounter = NULL; intrc; -Bool newcounter = FALSE; +Bool newSyncObject = FALSE; if (changes XSyncCACounter) { @@ -281,7 +281,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, { /* new counter for trigger */ SyncDeleteTriggerFromSyncObject(pTrigger); pTrigger-pSync = pSync; - newcounter = TRUE; + newSyncObject = TRUE; } } @@ -310,30 +310,37 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, if (changes XSyncCATestType) { - if (pTrigger-test_type != XSyncPositiveTransition - pTrigger-test_type != XSyncNegativeTransition - pTrigger-test_type != XSyncPositiveComparison - pTrigger-test_type != XSyncNegativeComparison) + if (SYNC_FENCE == pSync-type) { - client-errorValue = pTrigger-test_type; - return BadValue; + pTrigger-CheckTrigger = SyncCheckTriggerFence; } - /* select appropriate CheckTrigger function */ - - switch (pTrigger-test_type) + else { -case XSyncPositiveTransition: - pTrigger-CheckTrigger = SyncCheckTriggerPositiveTransition; - break; -case XSyncNegativeTransition: - pTrigger-CheckTrigger = SyncCheckTriggerNegativeTransition; - break; -case XSyncPositiveComparison: - pTrigger-CheckTrigger = SyncCheckTriggerPositiveComparison; - break; -case XSyncNegativeComparison: - pTrigger-CheckTrigger = SyncCheckTriggerNegativeComparison; - break; + if (pTrigger-test_type != XSyncPositiveTransition + pTrigger-test_type != XSyncNegativeTransition + pTrigger-test_type != XSyncPositiveComparison + pTrigger-test_type != XSyncNegativeComparison) + { + client-errorValue = pTrigger-test_type; + return BadValue; + } + /* select appropriate CheckTrigger function */ + + switch (pTrigger-test_type) + { + case XSyncPositiveTransition: + pTrigger-CheckTrigger = SyncCheckTriggerPositiveTransition; + break; + case XSyncNegativeTransition: + pTrigger-CheckTrigger = SyncCheckTriggerNegativeTransition; + break; + case XSyncPositiveComparison: + pTrigger-CheckTrigger = SyncCheckTriggerPositiveComparison; + break; + case XSyncNegativeComparison: + pTrigger-CheckTrigger = SyncCheckTriggerNegativeComparison; + break; + } } } @@ -360,7 +367,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject, /* we wait until we're sure there are no errors before registering * a new counter on a trigger */ -if (newcounter) +if (newSyncObject) { if ((rc = SyncAddTriggerToSyncObject(pTrigger)) != Success) return rc; @@ -607,14 +614,7 @@ SyncAwaitTriggerFired(SyncTrigger *pTrigger) continue; } - if (SYNC_FENCE == pAwait-trigger.pSync-type) - { - SyncFence *pFence = (SyncFence *) pAwait-trigger.pSync; - - if (pFence-triggered) - ppAwait[num_events++] = pAwait; - } - else if (SYNC_COUNTER == pAwait-trigger.pSync-type) + if (SYNC_COUNTER == pAwait-trigger.pSync-type) { SyncCounter *pCounter = (SyncCounter *) pAwait-trigger.pSync; @@ -654,10 +654,6 @@ SyncAwaitTriggerFired(SyncTrigger *pTrigger) ppAwait[num_events++] = pAwait; } } - else - { - FatalError(Invalid sync object type); - } } if (num_events) SyncSendCounterNotifyEvents(pAwaitUnion-header.client, ppAwait, @@ -1491,6 +1487,66 @@ ProcSyncDestroyCounter(ClientPtr client) return Success; } +static SyncAwaitUnion* +SyncAwaitPrologue(ClientPtr client, int items
[PATCH xserver (rev2) 4/9] Make Await SyncTrigger functions generic
Update all the functions dealing with Await sync triggers handle generic sync objects instead of just counters. This will facilitate code sharing between the counter sync waits and the fence sync waits. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- Xext/sync.c| 312 +--- Xext/syncsrv.h |2 +- 2 files changed, 210 insertions(+), 104 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 0c6de8d..7cff365 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -108,18 +108,19 @@ static void SyncInitIdleTime(void); * delete and add triggers on this list. */ static void -SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) +SyncDeleteTriggerFromSyncObject(SyncTrigger *pTrigger) { SyncTriggerList *pCur; SyncTriggerList *pPrev; +SyncCounter *pCounter; -/* pCounter needs to be stored in pTrigger before calling here. */ +/* pSync needs to be stored in pTrigger before calling here. */ -if (!pTrigger-pCounter) +if (!pTrigger-pSync) return; pPrev = NULL; -pCur = pTrigger-pCounter-sync.pTriglist; +pCur = pTrigger-pSync-pTriglist; while (pCur) { @@ -128,7 +129,7 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) if (pPrev) pPrev-next = pCur-next; else - pTrigger-pCounter-sync.pTriglist = pCur-next; + pTrigger-pSync-pTriglist = pCur-next; free(pCur); break; @@ -138,21 +139,27 @@ SyncDeleteTriggerFromCounter(SyncTrigger *pTrigger) pCur = pCur-next; } -if (IsSystemCounter(pTrigger-pCounter)) - SyncComputeBracketValues(pTrigger-pCounter); +if (SYNC_COUNTER == pTrigger-pSync-type) +{ + pCounter = (SyncCounter *)pTrigger-pSync; + + if (IsSystemCounter(pCounter)) + SyncComputeBracketValues(pCounter); +} } static int -SyncAddTriggerToCounter(SyncTrigger *pTrigger) +SyncAddTriggerToSyncObject(SyncTrigger *pTrigger) { SyncTriggerList *pCur; +SyncCounter *pCounter; -if (!pTrigger-pCounter) +if (!pTrigger-pSync) return Success; /* don't do anything if it's already there */ -for (pCur = pTrigger-pCounter-sync.pTriglist; pCur; pCur = pCur-next) +for (pCur = pTrigger-pSync-pTriglist; pCur; pCur = pCur-next) { if (pCur-pTrigger == pTrigger) return Success; @@ -162,11 +169,16 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) return BadAlloc; pCur-pTrigger = pTrigger; -pCur-next = pTrigger-pCounter-sync.pTriglist; -pTrigger-pCounter-sync.pTriglist = pCur; +pCur-next = pTrigger-pSync-pTriglist; +pTrigger-pSync-pTriglist = pCur; -if (IsSystemCounter(pTrigger-pCounter)) - SyncComputeBracketValues(pTrigger-pCounter); +if (SYNC_COUNTER == pTrigger-pSync-type) +{ + pCounter = (SyncCounter *)pTrigger-pSync; + + if (IsSystemCounter(pCounter)) + SyncComputeBracketValues(pCounter); +} return Success; } @@ -189,69 +201,100 @@ SyncAddTriggerToCounter(SyncTrigger *pTrigger) static Bool SyncCheckTriggerPositiveComparison(SyncTrigger *pTrigger, CARD64 oldval) { -return (pTrigger-pCounter == NULL || - XSyncValueGreaterOrEqual(pTrigger-pCounter-value, -pTrigger-test_value)); +SyncCounter *pCounter; + +assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +pCounter = (SyncCounter *)pTrigger-pSync; + +return (pCounter == NULL || + XSyncValueGreaterOrEqual(pCounter-value, pTrigger-test_value)); } static Bool SyncCheckTriggerNegativeComparison(SyncTrigger *pTrigger, CARD64 oldval) { -return (pTrigger-pCounter == NULL || - XSyncValueLessOrEqual(pTrigger-pCounter-value, - pTrigger-test_value)); +SyncCounter *pCounter; + +assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +pCounter = (SyncCounter *)pTrigger-pSync; + +return (pCounter == NULL || + XSyncValueLessOrEqual(pCounter-value, pTrigger-test_value)); } static Bool SyncCheckTriggerPositiveTransition(SyncTrigger *pTrigger, CARD64 oldval) { -return (pTrigger-pCounter == NULL || +SyncCounter *pCounter; + +assert(!pTrigger-pSync || (SYNC_COUNTER == pTrigger-pSync-type)); +pCounter = (SyncCounter *)pTrigger-pSync; + +return (pCounter == NULL || (XSyncValueLessThan(oldval, pTrigger-test_value) -XSyncValueGreaterOrEqual(pTrigger-pCounter-value, - pTrigger-test_value))); +XSyncValueGreaterOrEqual(pCounter-value, pTrigger-test_value))); } static Bool SyncCheckTriggerNegativeTransition(SyncTrigger *pTrigger, CARD64 oldval) { -return (pTrigger-pCounter == NULL || +SyncCounter *pCounter
[PATCH xserver (rev2) 9/9] Export SyncVerifyFence() in new SDK header
Add syncsdk.h, a new xorg SDK header. It contains SyncVerifyFence() and the helper functions that use it to look up fence sync objects. Exporting this functionality in an SDK header allows 3rd party extensions to look up fence objects in their interop APIs. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- Xext/Makefile.am |3 +- Xext/sync.c |1 + Xext/syncsdk.h | 47 ++ Xext/syncsrv.h | 17 --- damageext/damageext.c|4 +- hw/xfree86/loader/sdksyms.sh |1 + 6 files changed, 53 insertions(+), 20 deletions(-) create mode 100644 Xext/syncsdk.h diff --git a/Xext/Makefile.am b/Xext/Makefile.am index e444fd0..b6c95cb 100644 --- a/Xext/Makefile.am +++ b/Xext/Makefile.am @@ -15,7 +15,7 @@ INCLUDES = -I$(top_srcdir)/hw/xfree86/dixmods/extmod AM_CFLAGS = $(DIX_CFLAGS) if XORG -sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h +sdk_HEADERS = xvdix.h xvmcext.h geext.h geint.h shmint.h syncsdk.h endif # Sources always included in libXextbuiltin.la libXext.la @@ -26,6 +26,7 @@ BUILTIN_SRCS =\ sleepuntil.c\ sleepuntil.h\ sync.c \ + syncsdk.h \ syncsrv.h \ xcmisc.c\ xtest.c diff --git a/Xext/sync.c b/Xext/sync.c index 3ca4d68..1af3b03 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -68,6 +68,7 @@ PERFORMANCE OF THIS SOFTWARE. #include opaque.h #include X11/extensions/syncproto.h #include syncsrv.h +#include syncsdk.h #include stdio.h #if !defined(WIN32) diff --git a/Xext/syncsdk.h b/Xext/syncsdk.h new file mode 100644 index 000..a72c585 --- /dev/null +++ b/Xext/syncsdk.h @@ -0,0 +1,47 @@ +/* + * Copyright © 2010 NVIDIA Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the Software), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef _SYNCSDK_H_ +#define _SYNCSDK_H_ + +#include misync.h + +extern _X_EXPORT int +SyncVerifyFence(SyncFence **ppFence, XID fid, ClientPtr client, Mask mode); + +#define VERIFY_SYNC_FENCE(pFence, fid, client, mode) \ +do { \ + int rc; \ + rc = SyncVerifyFence((pFence), (fid), (client), (mode)); \ + if (Success != rc) return rc; \ +} while (0) + +#define VERIFY_SYNC_FENCE_OR_NONE(pFence, fid, client, mode) \ +do { \ +pFence = 0;\ +if (None != fid) \ + VERIFY_SYNC_FENCE((pFence), (fid), (client), (mode)); \ +} while (0) + +#endif /* _SYNCSDK_H_ */ + diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 14d6019..7ca1fba 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -140,23 +140,6 @@ extern void SyncDestroySystemCounter( pointer pCounter ); -extern int SyncVerifyFence(SyncFence **ppFence, XID fid, - ClientPtr client, Mask mode); - -#define VERIFY_SYNC_FENCE(pFence, fid, client, mode) \ -do { \ - int rc; \ - rc = SyncVerifyFence((pFence), (fid), (client), (mode)); \ - if (Success != rc) return rc; \ -} while (0) - -#define VERIFY_SYNC_FENCE_OR_NONE(pFence, fid, client, mode) \ -do { \ -pFence = 0
[PATCH xserver (rev2) 7/9] Add XDamageSubtractAndTrigger operation
XDamageSubtractAndTrigger behaves exactly like XDamageSubtract except it receives an optional fence sync object. If the value of this object is not None, it is triggered by X once all the rendering associated with the damage regions being subtracted has completed. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- COPYING |2 +- Xext/sync.c | 27 +++--- Xext/syncsrv.h | 68 ++ configure.ac| 21 ++- damageext/damageext.c | 64 +++-- include/protocol-versions.h |2 +- miext/Makefile.am |4 +- miext/sync/Makefile.am | 14 +++ miext/sync/misync.c | 44 ++ miext/sync/misync.h | 36 ++ miext/sync/misyncstr.h | 84 +++ 11 files changed, 280 insertions(+), 86 deletions(-) create mode 100644 miext/sync/Makefile.am create mode 100644 miext/sync/misync.c create mode 100644 miext/sync/misync.h create mode 100644 miext/sync/misyncstr.h diff --git a/COPYING b/COPYING index 3fb06b8..3aad5fa 100644 --- a/COPYING +++ b/COPYING @@ -14,7 +14,7 @@ Copyright © 2006-2007 Intel Corporation Copyright © 2006 Nokia Corporation Copyright © 2006-2008 Peter Hutterer Copyright © 2006 Adam Jackson -Copyright © 2009 NVIDIA Corporation +Copyright © 2009-2010 NVIDIA Corporation Copyright © 1999 Keith Packard Copyright © 2007-2009 Red Hat, Inc. Copyright © 2005-2008 Daniel Stone diff --git a/Xext/sync.c b/Xext/sync.c index aee2ca1..9b087f6 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -1935,13 +1935,23 @@ FreeFence(void *obj, XID id) return Success; } +int SyncVerifyFence(SyncFence **ppSyncFence, XID fid, + ClientPtr client, Mask mode) +{ +int rc = dixLookupResourceByType((pointer *)ppSyncFence, fid, RTFence, +client, mode); + +if (rc != Success) + client-errorValue = fid; + +return rc; +} + static int ProcSyncTriggerFence(ClientPtr client) { REQUEST(xSyncTriggerFenceReq); SyncFence *pFence; -SyncTriggerList *ptl, *pNext; -CARD64 unused; int rc; REQUEST_SIZE_MATCH(xSyncTriggerFenceReq); @@ -1951,17 +1961,7 @@ ProcSyncTriggerFence(ClientPtr client) if (rc != Success) return rc; -pFence-triggered = TRUE; - -XSyncIntToValue(unused, 0L); - -/* run through triggers to see if any fired */ -for (ptl = pFence-sync.pTriglist; ptl; ptl = pNext) -{ - pNext = ptl-next; - if ((*ptl-pTrigger-CheckTrigger)(ptl-pTrigger, unused)) - (*ptl-pTrigger-TriggerFired)(ptl-pTrigger); -} +miSyncTriggerFence(pFence); return client-noClientException; } @@ -2548,7 +2548,6 @@ SyncResetProc(ExtensionEntry *extEntry) RTCounter = 0; } - /* * ** Initialise the extension. */ diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 99c8bf4..14d6019 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -51,31 +51,8 @@ PERFORMANCE OF THIS SOFTWARE. #ifndef _SYNCSRV_H_ #define _SYNCSRV_H_ -#define CARD64 XSyncValue /* XXX temporary! need real 64 bit values for Alpha */ - -/* Sync object types */ -#define SYNC_COUNTER 0 -#define SYNC_FENCE 1 - -typedef struct _SyncObject { -ClientPtr client; /* Owning client. 0 for system counters */ -struct _SyncTriggerList *pTriglist;/* list of triggers */ -XIDid; /* resource ID */ -unsigned char type; /* SYNC_* */ -Bool beingDestroyed; /* in process of going away */ -} SyncObject; - -typedef struct _SyncCounter { -SyncObject sync; /* Common sync object data */ -CARD64 value; /* counter value */ -struct _SysCounterInfo *pSysCounterInfo; /* NULL if not a system counter */ -} SyncCounter; - -typedef struct _SyncFence { -SyncObject sync; /* Common sync object data */ -ScreenPtr pScreen; /* Screen of this fence object */ -Bool triggered; /* fence state */ -} SyncFence; +#include misync.h +#include misyncstr.h /* * The System Counter interface @@ -107,29 +84,6 @@ typedef struct _SysCounterInfo { -typedef struct _SyncTrigger { -SyncObject *pSync; -CARD64 wait_value; /* wait value */ -unsigned int value_type; /* Absolute or Relative */ -unsigned int test_type;/* transition or Comparision type */ -CARD64 test_value; /* trigger event threshold value */ -Bool (*CheckTrigger)( - struct _SyncTrigger * /*pTrigger*/, - CARD64 /*newval*/ - ); -void (*TriggerFired
[PATCH xextproto 0/4] XSync Fence Objects (rev. 3)
Updated again to include some clarifications in the documentation suggested by Adam Jackson. Adds support for binary sync objects. Objects are set to triggered using X commands that are executed relative to X rendering commands. Clients can wait for fence sync objcts to reach the triggered state using XSync APIs or using interop functionality in other APIs. This allows for efficient cross-API synchronization with X rendering operations. Now includes modifications suggested by Alan Coopersmith and protocol spec updates. Alan, I've looked into the heroics needed to provide backwards compatibility with older servers/newer libXexts, and it looks like it will all be in the lib code, which I'll be sending out once I implement said heroics. Thanks for pointing this out. The lib change to enable backwards compatibility should go in before these proto changes because the lib code is currently written such that it will refuse to work with any server advertising an XSync version below whatever the lib code picks up from compile-time constants in xextproto. James Jones (4): Document changes in XSync version 3.1 Initial Fence Sync support Add XSyncQueryFence() Add protocol for XSyncAwaitFence() specs/sync.xml | 229 +-- syncconst.h|6 +- syncproto.h| 96 +++ 3 files changed, 320 insertions(+), 11 deletions(-) ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xextproto 1/4] Document changes in XSync version 3.1
Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Pierre-Loup Griffais pgriff...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com Reviewed-by: Robert Morell rmor...@nvidia.com --- specs/sync.xml | 229 +-- 1 files changed, 220 insertions(+), 9 deletions(-) diff --git a/specs/sync.xml b/specs/sync.xml index a8064a9..e61dc17 100644 --- a/specs/sync.xml +++ b/specs/sync.xml @@ -32,6 +32,11 @@ by TeX4ht (http://www.cse.ohio-state.edu/~gurari/TeX4ht/) xhtml,docbook,html,ref surnameWiggins/surname affiliationorgnameX Consortium, Inc./orgname/affiliation /othercredit + othercredit + firstnameJames/firstname + surnameJones/surname + affiliationorgnameNVIDIA Corporation/orgname/affiliation + /othercredit /authorgroup corpnameX Consortium Standard/corpname @@ -43,8 +48,9 @@ Digital Equipment Corporation, Maynard, Massachusetts /holder /copyright copyrightyear1991/yearholderX Consortium/holder/copyright + copyrightyear2010/yearholderNVIDIA Corporation/holder/copyright - releaseinfoVersion 3.0/releaseinfo + releaseinfoVersion 3.1/releaseinfo affiliationorgnameX Consortium/orgname/affiliation productnumberX Version 11, Release 6.8/productnumber @@ -52,10 +58,10 @@ Digital Equipment Corporation, Maynard, Massachusetts para Permission to use, copy, modify, and distribute this documentation for any purpose and without fee is hereby granted, provided that the above -copyright notice appear in all copies. Olivetti, Digital, MIT, and the -X Consortium make no representations about the suitability for any purpose -of the information in this document. This documentation is provided as -is without express or implied warranty. +copyright notice appear in all copies. Olivetti, Digital, MIT, the +X Consortium, and NVIDIA make no representations about the suitability for +any purpose of the information in this document. This documentation is +provided as is without express or implied warranty. /para para @@ -133,12 +139,17 @@ frame marker. /para para -The extension adds functionCounter/function and -functionAlarm/function to the set of resources managed by the +The extension adds functionCounter/function, functionAlarm/function, +and functionFence/function to the set of resources managed by the server. A counter has a 64-bit integer value that may be increased or decreased by client requests or by the server internally. A client can block by sending an Await request that waits until one of a set of synchronization -conditions, called TRIGGERs, becomes TRUE. +conditions, called TRIGGERs, becomes TRUE. Alarms generate events when +counter values go through a specified transition. A fence has two possible +states: triggered and not triggered. Client requests can put the fence in +either of these states. A client can block until one of a set of fences +becomes triggered by sending an AwaitFence request. Fences are bound to a +particular screen at creation time. /para para @@ -168,6 +179,21 @@ clients to receive an event on a regular basis when a particular counter is changed. /para +para +The functionCreateFence/function request allows a client to create a +functionFence/function that can be triggered and reset using +functionTriggerFence/function and functionResetFence/function +requests, respectively. functionCreateFence/function takes a drawable +argument that implies which screen the fence should be created on. The +functionTriggerFence/function request changes the fence's state only +after all previous rendering commands affecting objects owned by the given +fence's screen have completed. Note that while fence objects are bound +to a screen and the simple trigger operation provided by this extension +operates at screen granularity, other extensions may add more fine-grained +trigger operations based on any number of events. The screen binding +merely establishes an upper bound for the scope of fence operations. +/para + /sect1 sect1 id=types titleTypes/title @@ -201,6 +227,7 @@ SYSTEMCOUNTER: [ ] ALARM: XID ALARMSTATE:{Active,Inactive,Destroyed} +FENCE: XID /literallayout para @@ -283,6 +310,14 @@ registry of system counter names to avoid collisions in the name space. para An ALARM is the client-side handle on an functionAlarm/function resource. /para + +para +The FENCE type defines the client-side handle on a server +functionFence/function. A fence can only be in one of two states, +represented by a BOOL. If the value is TRUE, the fence is in the triggered +state. Otherwise, the fence is in the not triggered state. +/para + /sect1 sect1 id=errors @@ -307,6 +342,15 @@ does not name a defined ALARM. /para /listitem /varlistentry + varlistentry +termFence/term +listitem + para +This error is generated if the value
[PATCH xextproto 2/4] Initial Fence Sync support
Defines the protocol for creation and basic management of binary state sync objects. The following operations are defined: -Creation -Destruction -Trigger -Reset Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- syncconst.h |6 -- syncproto.h | 56 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/syncconst.h b/syncconst.h index 926b60c..3acc387 100644 --- a/syncconst.h +++ b/syncconst.h @@ -54,7 +54,7 @@ PERFORMANCE OF THIS SOFTWARE. #define SYNC_NAME SYNC #define SYNC_MAJOR_VERSION 3 -#define SYNC_MINOR_VERSION 0 +#define SYNC_MINOR_VERSION 1 #define XSyncCounterNotify 0 @@ -65,7 +65,8 @@ PERFORMANCE OF THIS SOFTWARE. #define XSyncBadCounter0L #define XSyncBadAlarm 1L -#define XSyncNumberErrors (XSyncBadAlarm + 1) +#define XSyncBadFence 2L +#define XSyncNumberErrors (XSyncBadFence + 1) /* * Flags for Alarm Attributes @@ -172,6 +173,7 @@ typedef enum { typedef XID XSyncCounter; typedef XID XSyncAlarm; +typedef XID XSyncFence; typedef struct _XSyncValue { int hi; unsigned int lo; diff --git a/syncproto.h b/syncproto.h index 13b53d5..c38ea84 100644 --- a/syncproto.h +++ b/syncproto.h @@ -67,6 +67,10 @@ PERFORMANCE OF THIS SOFTWARE. #define X_SyncDestroyAlarm11 #define X_SyncSetPriority 12 #define X_SyncGetPriority 13 +#define X_SyncCreateFence 14 +#define X_SyncTriggerFence15 +#define X_SyncResetFence 16 +#define X_SyncDestroyFence17 /* cover up types from sync.h to make sure they're the right size for * protocol packaging. These will be undef'ed after all the protocol @@ -74,6 +78,8 @@ PERFORMANCE OF THIS SOFTWARE. */ #define XSyncCounter CARD32 #define XSyncAlarm CARD32 +#define XSyncFence CARD32 +#define Drawable CARD32 /* * Initialize @@ -337,6 +343,54 @@ typedef struct { #define sz_xSyncGetPriorityReply 32 /* + * Create Fence + */ +typedef struct _xSyncCreateFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +Drawable d B32; +XSyncFence fid B32; +BOOL initially_triggered; +CARD8 pad0; +CARD16 pad1; +} xSyncCreateFenceReq; +#define sz_xSyncCreateFenceReq 16 + +/* + * Put a fence object in the triggered state. + */ +typedef struct _xSyncTriggerFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +XSyncFence fid B32; +} xSyncTriggerFenceReq; +#define sz_xSyncTriggerFenceReq8 + +/* + * Put a fence in the untriggered state. + */ +typedef struct _xSyncResetFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +XSyncFence fid B32; +} xSyncResetFenceReq; +#define sz_xSyncResetFenceReq 8 + +/* + * Destroy a fence object + */ +typedef struct _xSyncDestroyFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +XSyncFence fid B32; +} xSyncDestroyFenceReq; +#define sz_xSyncDestroyFenceReq8 + +/* * Events */ @@ -373,6 +427,8 @@ typedef struct _xSyncAlarmNotifyEvent { #undef XSyncCounter #undef XSyncAlarm +#undef XSyncFence +#undef Drawable #endif /* _SYNCPROTO_H_ */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xextproto 3/4] Add XSyncQueryFence()
Allows callers to query whether a given fence sync object is currently triggered or not. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- syncproto.h | 28 1 files changed, 28 insertions(+), 0 deletions(-) diff --git a/syncproto.h b/syncproto.h index c38ea84..7e0a568 100644 --- a/syncproto.h +++ b/syncproto.h @@ -71,6 +71,7 @@ PERFORMANCE OF THIS SOFTWARE. #define X_SyncTriggerFence15 #define X_SyncResetFence 16 #define X_SyncDestroyFence17 +#define X_SyncQueryFence 18 /* cover up types from sync.h to make sure they're the right size for * protocol packaging. These will be undef'ed after all the protocol @@ -391,6 +392,33 @@ typedef struct _xSyncDestroyFenceReq { #define sz_xSyncDestroyFenceReq8 /* + * Query a fence object + */ +typedef struct _xSyncQueryFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +XSyncFence fid B32; +} xSyncQueryFenceReq; +#define sz_xSyncQueryFenceReq 8 + +typedef struct { +BYTE type; +CARD8 unused; +CARD16 sequenceNumber B16; +CARD32 length B32; +BOOL triggered; +BYTE pad0; +CARD16 pad1 B16; +CARD32 pad2 B32; +CARD32 pad3 B32; +CARD32 pad4 B32; +CARD32 pad5 B32; +CARD32 pad6 B32; +} xSyncQueryFenceReply; +#define sz_xSyncQueryFenceReply32 + +/* * Events */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xextproto 4/4] Add protocol for XSyncAwaitFence()
Add the fence sync object equivalent of XSyncAwait() Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- syncproto.h | 12 1 files changed, 12 insertions(+), 0 deletions(-) diff --git a/syncproto.h b/syncproto.h index 7e0a568..1453e44 100644 --- a/syncproto.h +++ b/syncproto.h @@ -72,6 +72,7 @@ PERFORMANCE OF THIS SOFTWARE. #define X_SyncResetFence 16 #define X_SyncDestroyFence17 #define X_SyncQueryFence 18 +#define X_SyncAwaitFence 19 /* cover up types from sync.h to make sure they're the right size for * protocol packaging. These will be undef'ed after all the protocol @@ -402,6 +403,17 @@ typedef struct _xSyncQueryFenceReq { } xSyncQueryFenceReq; #define sz_xSyncQueryFenceReq 8 +/* + * Wait for any of a list of fence sync objects + * to reach the triggered state. + */ +typedef struct _xSyncAwaitFenceReq { +CARD8 reqType; +CARD8 syncReqType; +CARD16 length B16; +} xSyncAwaitFenceReq; +#define sz_xSyncAwaitFenceReq 4 + typedef struct { BYTE type; CARD8 unused; -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXext] Backwards compat for newer XSync + older servers
Add infrastructure to make future builds of libXext that support version of XSync 3.1 compatibile with X servers exporting XSync version 3.0. As part of this, don't handle errors introduced by newer versions of the protocol than the server supports. Those error codes could be used by some other extension. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- src/XSync.c | 125 +- 1 files changed, 97 insertions(+), 28 deletions(-) diff --git a/src/XSync.c b/src/XSync.c index 648c718..553bbf1 100644 --- a/src/XSync.c +++ b/src/XSync.c @@ -95,19 +95,103 @@ static char*sync_error_list[] = { BadAlarm, }; +typedef struct _SyncVersionInfoRec { +short major; +short minor; +int num_errors; +} SyncVersionInfo; + +static /* const */ SyncVersionInfo supported_versions[] = { +{ 3 /* major */, 0 /* minor */, 2 /* num_errors */ }, +}; + +#define NUM_VERSIONS (sizeof(supported_versions)/sizeof(supported_versions[0])) +#define GET_VERSION(info) ((info) ? (const SyncVersionInfo*)(info)-data : NULL) +#define IS_VERSION_SUPPORTED(info) (!!GET_VERSION(info)) + +static +const SyncVersionInfo* GetVersionInfo(Display *dpy) +{ +xSyncInitializeReply rep; +xSyncInitializeReq *req; +XExtCodes codes; +int i; + +if (!XQueryExtension(dpy, sync_extension_name, + codes.major_opcode, + codes.first_event, + codes.first_error)) +return NULL; + +LockDisplay(dpy); +GetReq(SyncInitialize, req); +req-reqType = codes.major_opcode; +req-syncReqType = X_SyncInitialize; +req-majorVersion = SYNC_MAJOR_VERSION; +req-minorVersion = SYNC_MINOR_VERSION; +if (!_XReply(dpy, (xReply *) rep, 0, xTrue)) +{ + UnlockDisplay(dpy); + SyncHandle(); + return NULL; +} +UnlockDisplay(dpy); +SyncHandle(); + +for (i = 0; i NUM_VERSIONS; i++) { + if (supported_versions[i].major == rep.majorVersion + supported_versions[i].minor == rep.minorVersion) { + return supported_versions[i]; + } +} + +return NULL; +} + +static +XExtDisplayInfo *find_display_create_optional(Display *dpy, Bool create) +{ +XExtDisplayInfo *dpyinfo; + +if (!sync_info) { +if (!(sync_info = XextCreateExtension())) return NULL; +} + +if (!(dpyinfo = XextFindDisplay (sync_info, dpy)) create) { +dpyinfo = XextAddDisplay(sync_info, dpy, + sync_extension_name, + sync_extension_hooks, + XSyncNumberEvents, + (XPointer)GetVersionInfo(dpy)); +} + +return dpyinfo; +} + static -XEXT_GENERATE_FIND_DISPLAY(find_display, sync_info, - sync_extension_name, - sync_extension_hooks, - XSyncNumberEvents, (XPointer) NULL) +XExtDisplayInfo *find_display (Display *dpy) +{ +return find_display_create_optional(dpy, True); +} static XEXT_GENERATE_CLOSE_DISPLAY(close_display, sync_info) static -XEXT_GENERATE_ERROR_STRING(error_string, sync_extension_name, - XSyncNumberErrors, sync_error_list) +char *error_string(Display *dpy, int code, XExtCodes *codes, char *buf, int n) +{ +XExtDisplayInfo *info = find_display_create_optional(dpy, False); +int nerr = IS_VERSION_SUPPORTED(info) ? GET_VERSION(info)-num_errors : 0; +code -= codes-first_error; +if (code = 0 code nerr) { + char tmp[256]; + sprintf (tmp, %s.%d, sync_extension_name, code); + XGetErrorDatabaseText (dpy, XProtoError, tmp, sync_error_list[code], buf, n); + return buf; +} +return (char *)0; +} static Bool wire_to_event(Display *dpy, XEvent *event, xEvent *wire) @@ -232,32 +316,17 @@ XSyncInitialize( int *major_version_return, int *minor_version_return) { XExtDisplayInfo *info = find_display(dpy); -xSyncInitializeReply rep; -xSyncInitializeReq *req; SyncCheckExtension(dpy, info, False); -LockDisplay(dpy); -GetReq(SyncInitialize, req); -req-reqType = info-codes-major_opcode; -req-syncReqType = X_SyncInitialize; -req-majorVersion = SYNC_MAJOR_VERSION; -req-minorVersion = SYNC_MINOR_VERSION; -if (!_XReply(dpy, (xReply *) rep, 0, xTrue)) -{ - UnlockDisplay(dpy); - SyncHandle(); +if (IS_VERSION_SUPPORTED(info)) { + *major_version_return = GET_VERSION(info)-major; + *minor_version_return = GET_VERSION(info)-minor; + + return True; +} else { return False; } -UnlockDisplay(dpy); -SyncHandle(); -*major_version_return = rep.majorVersion; -*minor_version_return = rep.minorVersion; -return ((rep.majorVersion == SYNC_MAJOR_VERSION) -#if SYNC_MINOR_VERSION 0 /* avoid compiler
[PATCH libXext 0/3] XSync Fence Objects, lib portion
Adds client library support for binary sync objects added in the X Synchronization protocol version 3.1. libXext remains compatible with servers that only implement version 3.0 James Jones (3): Initial Fence Sync Object support Add XSyncQueryFence() Add XSyncAwaitFence() include/X11/extensions/sync.h | 33 ++ src/XSync.c | 135 + 2 files changed, 168 insertions(+), 0 deletions(-) ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXext 1/3] Initial Fence Sync Object support
Allows creating and managing binary state sync objects. Currently they aren't useful because there is not yet a way to wait for them or query their state. X fence objects are owned by a screen. As Aaron Plattner pointed out, screens are identified by a drawable in X protocol, so XSyncCreateFence() takes a drawable to identify which screen to create the fence on. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- include/X11/extensions/sync.h | 21 ++ src/XSync.c | 85 + 2 files changed, 106 insertions(+), 0 deletions(-) diff --git a/include/X11/extensions/sync.h b/include/X11/extensions/sync.h index b327f69..5b157f8 100644 --- a/include/X11/extensions/sync.h +++ b/include/X11/extensions/sync.h @@ -337,6 +337,27 @@ extern Status XSyncGetPriority( int* /*return_priority*/ ); +extern XSyncFence XSyncCreateFence( +Display* /*dpy*/, +Drawable /*d*/, +Bool /*initially_triggered*/ +); + +extern Bool XSyncTriggerFence( +Display* /*dpy*/, +XSyncFence /*fence*/ +); + +extern Bool XSyncResetFence( +Display* /*dpy*/, +XSyncFence /*fence*/ +); + +extern Bool XSyncDestroyFence( +Display* /*dpy*/, +XSyncFence /*fence*/ +); + _XFUNCPROTOEND #endif /* _SYNC_SERVER */ diff --git a/src/XSync.c b/src/XSync.c index 553bbf1..fdc5e33 100644 --- a/src/XSync.c +++ b/src/XSync.c @@ -93,6 +93,7 @@ static XExtensionHooks sync_extension_hooks = { static char*sync_error_list[] = { BadCounter, BadAlarm, +BadFence, }; typedef struct _SyncVersionInfoRec { @@ -103,6 +104,7 @@ typedef struct _SyncVersionInfoRec { static /* const */ SyncVersionInfo supported_versions[] = { { 3 /* major */, 0 /* minor */, 2 /* num_errors */ }, +{ 3 /* major */, 1 /* minor */, 3 /* num_errors */ }, }; #define NUM_VERSIONS (sizeof(supported_versions)/sizeof(supported_versions[0])) @@ -761,6 +763,89 @@ XSyncGetPriority(Display *dpy, XID client_resource_id, int *return_priority) return True; } +XSyncFence +XSyncCreateFence(Display *dpy, Drawable d, Bool initially_triggered) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncCreateFenceReq *req; +XSyncFence id; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncCreateFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncCreateFence; + +req-d = d; +id = req-fid = XAllocID(dpy); +req-initially_triggered = initially_triggered; + +UnlockDisplay(dpy); +SyncHandle(); +return id; +} + +Bool +XSyncTriggerFence(Display *dpy, XSyncFence fence) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncTriggerFenceReq *req; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncTriggerFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncTriggerFence; + +req-fid = fence; + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + +Bool +XSyncResetFence(Display *dpy, XSyncFence fence) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncResetFenceReq *req; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncResetFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncResetFence; + +req-fid = fence; + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + +Bool +XSyncDestroyFence(Display *dpy, XSyncFence fence) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncDestroyFenceReq *req; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncDestroyFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncDestroyFence; + +req-fid = fence; + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + /* * Functions corresponding to the macros for manipulating 64-bit values */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXext 2/3] Add XSyncQueryFence()
Allows callers to query whether or not a given fence sync object is currently triggered. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- include/X11/extensions/sync.h |6 ++ src/XSync.c | 29 + 2 files changed, 35 insertions(+), 0 deletions(-) diff --git a/include/X11/extensions/sync.h b/include/X11/extensions/sync.h index 5b157f8..05a5a98 100644 --- a/include/X11/extensions/sync.h +++ b/include/X11/extensions/sync.h @@ -358,6 +358,12 @@ extern Bool XSyncDestroyFence( XSyncFence /*fence*/ ); +extern Bool XSyncQueryFence( +Display* /*dpy*/, +XSyncFence /*fence*/, +Bool* /*triggered*/ +); + _XFUNCPROTOEND #endif /* _SYNC_SERVER */ diff --git a/src/XSync.c b/src/XSync.c index fdc5e33..0dcacc4 100644 --- a/src/XSync.c +++ b/src/XSync.c @@ -846,6 +846,35 @@ XSyncDestroyFence(Display *dpy, XSyncFence fence) return True; } +Bool +XSyncQueryFence(Display *dpy, XSyncFence fence, Bool *triggered) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncQueryFenceReply rep; +xSyncQueryFenceReq *req; + +SyncCheckExtension(dpy, info, None); + +LockDisplay(dpy); +GetReq(SyncQueryFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncQueryFence; +req-fid = fence; + +if (!_XReply(dpy, (xReply *) rep, 0, xFalse)) +{ + UnlockDisplay(dpy); + SyncHandle(); + return False; +} +if (triggered) + *triggered = rep.triggered; + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + /* * Functions corresponding to the macros for manipulating 64-bit values */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXext 3/3] Add XSyncAwaitFence()
Add the XSynceFence version of XSyncAwait(). Waits for fence objects to reach the triggered state. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- include/X11/extensions/sync.h |6 ++ src/XSync.c | 21 + 2 files changed, 27 insertions(+), 0 deletions(-) diff --git a/include/X11/extensions/sync.h b/include/X11/extensions/sync.h index 05a5a98..46cefac 100644 --- a/include/X11/extensions/sync.h +++ b/include/X11/extensions/sync.h @@ -364,6 +364,12 @@ extern Bool XSyncQueryFence( Bool* /*triggered*/ ); +extern Bool XSyncAwaitFence( +Display* /*dpy*/, +const XSyncFence* /*fence_list*/, +int /*n_fences*/ +); + _XFUNCPROTOEND #endif /* _SYNC_SERVER */ diff --git a/src/XSync.c b/src/XSync.c index 0dcacc4..c1fcf86 100644 --- a/src/XSync.c +++ b/src/XSync.c @@ -875,6 +875,27 @@ XSyncQueryFence(Display *dpy, XSyncFence fence, Bool *triggered) return True; } +Bool +XSyncAwaitFence(Display *dpy, const XSyncFence *fence_list, int n_fences) +{ +XExtDisplayInfo *info = find_display(dpy); +xSyncAwaitFenceReq *req; + +SyncCheckExtension(dpy, info, False); + +LockDisplay(dpy); +GetReq(SyncAwaitFence, req); +req-reqType = info-codes-major_opcode; +req-syncReqType = X_SyncAwaitFence; +SetReqLen(req, n_fences, n_fences); + +Data32(dpy, (char *)fence_list, sizeof(CARD32) * n_fences); + +UnlockDisplay(dpy); +SyncHandle(); +return True; +} + /* * Functions corresponding to the macros for manipulating 64-bit values */ -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH libXdamage] Add XDamageSubtractAndTrigger operation
XDamageSubtractAndTrigger behaves exactly like XDamageSubtract except it receives an optional fence sync object. If the value of this object is not None, it is triggered by X once all the rendering associated with the damage regions being subtracted has completed. Signed-off-by: James Jones jajo...@nvidia.com Reviewed-by: Aaron Plattner aplatt...@nvidia.com --- include/X11/extensions/Xdamage.h |7 +++ src/Xdamage.c| 21 + 2 files changed, 28 insertions(+), 0 deletions(-) diff --git a/include/X11/extensions/Xdamage.h b/include/X11/extensions/Xdamage.h index 5ecf035..181601d 100644 --- a/include/X11/extensions/Xdamage.h +++ b/include/X11/extensions/Xdamage.h @@ -25,9 +25,11 @@ #include X11/extensions/damagewire.h #include X11/extensions/Xfixes.h +#include X11/extensions/syncconst.h #include X11/Xfuncproto.h #define XDAMAGE_1_1_INTERFACE +#define XDAMAGE_1_2_INTERFACE typedef XID Damage; @@ -68,6 +70,11 @@ XDamageSubtract (Display *dpy, Damage damage, void XDamageAdd (Display *dpy, Drawable drawable, XserverRegion region); +void +XDamageSubtractAndTrigger (Display *dpy, Damage damage, + XserverRegion repair, XserverRegion parts, + XSyncFence finishedFence); + _XFUNCPROTOEND #endif /* _XDAMAGE_H_ */ diff --git a/src/Xdamage.c b/src/Xdamage.c index 3a368d2..636ab48 100644 --- a/src/Xdamage.c +++ b/src/Xdamage.c @@ -383,3 +383,24 @@ XDamageAdd (Display *dpy, Drawable drawable, XserverRegion region) UnlockDisplay (dpy); SyncHandle (); } + +void +XDamageSubtractAndTrigger (Display *dpy, Damage damage, + XserverRegion repair, XserverRegion parts, + XSyncFence finishedFence) +{ +XDamageExtDisplayInfo *info = XDamageFindDisplay (dpy); +xDamageSubtractAndTriggerReq *req; + +XDamageSimpleCheckExtension (dpy, info); +LockDisplay (dpy); +GetReq (DamageSubtractAndTrigger, req); +req-reqType = info-codes-major_opcode; +req-damageReqType = X_DamageSubtractAndTrigger; +req-damage = damage; +req-repair = repair; +req-parts = parts; +req-finishedFence = finishedFence; +UnlockDisplay (dpy); +SyncHandle (); +} -- 1.7.1 ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
[PATCH xserver 0/9] X Server support for Fence Sync
Implements X Sync Fence Objects in the server, including the damage 1.2 support for DamageSubtractAndTrigger. Re- uses X Sync Counter code wherever possible. A driver interface has also been added so DDX drivers can redirect fence sync operations to HW rendering backend operations. James Jones (9): Create/Destroy/Trigger/Reset Fence Sync objects Add XSyncQueryFence() Create SyncObject base type. Make Await SyncTrigger functions generic Generalize comment above Sync CheckTriggered funcs Add XSyncAwaitFence() handler Add XDamageSubtractAndTrigger operation Add fence sync driver interface Export SyncVerifyFence() in new SDK header COPYING |2 +- Xext/Makefile.am |3 +- Xext/sync.c | 910 +- Xext/syncsdk.h | 47 +++ Xext/syncsrv.h | 37 +-- configure.ac | 21 +- damageext/damageext.c| 64 +++- dix/privates.c |1 + hw/xfree86/loader/sdksyms.sh |4 + include/privates.h |1 + include/protocol-versions.h |2 +- miext/Makefile.am|4 +- miext/X/Makefile.am | 14 + miext/X/misync.c | 189 + miext/X/misync.h | 77 miext/X/misyncstr.h | 86 16 files changed, 1206 insertions(+), 256 deletions(-) create mode 100644 Xext/syncsdk.h create mode 100644 miext/X/Makefile.am create mode 100644 miext/X/misync.c create mode 100644 miext/X/misync.h create mode 100644 miext/X/misyncstr.h ___ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel