Re: [PATCH] drm: Fix lock order reversal between mmap_sem and struct_mutex.
On Fri, 2009-02-20 at 08:36 +0100, Peter Zijlstra wrote: On Thu, 2009-02-19 at 18:04 -0800, Eric Anholt wrote: On Thu, 2009-02-19 at 23:26 +0100, Peter Zijlstra wrote: On Thu, 2009-02-19 at 22:02 +0100, Thomas Hellstrom wrote: It looks to me like the driver preferred locking order is object_mutex (which happens to be the device global struct_mutex) mmap_sem offset_mutex. So if one could avoid using the struct_mutex for object bookkeeping (A separate lock) then vm_open() and vm_close() would adhere to that locking order as well, simply by not taking the struct_mutex at all. So only fault() remains, in which that locking order is reversed. Personally I think the trylock -reschedule-retry method with proper commenting is a good solution. It will be the _only_ place where locking order is reversed and it is done in a deadlock-safe manner. Note that fault() doesn't really fail, but requests a retry from user-space with rescheduling to give the process holding the struct_mutex time to release it. It doesn't do the reschedule -- need_resched() will check if the current task was marked to be scheduled away, furthermore yield based locking sucks chunks. Imagine what would happen if your faulting task was the highest RT prio task in the system, you'd end up with a life-lock. What's so very difficult about pulling the copy_*_user() out from under the locks? That we're expecting the data movement to occur while holding device state in place. For example, we write data through the GTT most of the time so we: lock struct_mutex pin the object to the GTT flushing caches as needed copy_from_user unpin object unlock struct_mutex So you cannot drop the lock once you've pinned the dst object? If I'm to pull the copy_from_user out, that means I have to: alloc temporary storage for each block of temp storage size: copy_from_user lock struct_mutex pin the object to the GTT flush caches as needed memcpy unpin object unlock struct_mutex At this point of introducing our third copy of the user's data in our hottest path, we should probably ditch the pwrite path entirely and go to user mapping of the objects for performance. Requiring user mapping (which has significant overhead) cuts the likelihood of moving from user-space object caching to kernel object caching in the future, which has the potential of saving steaming piles of memory. Or you could get_user_pages() to fault the user pages and pin them, and then do pagefault_disable() and use copy_from_user_inatomic or such, and release the pages again. I started poking at this today, since the get_user_pages sounded like the solution. Only then I noticed: when we unbind an existing object, we have to unmap_mapping_range to clear the clients' mappings to it in the GTT, which needs to happen while the struct lock (protecting the gtt structure and the gtt to object mappings) is held. So for fault we have mmap_sem held to struct mutex taken for poking at the gtt structure, and for unbind we have struct mutex held to mmap_sem taken to clear mappings. -- Eric Anholt e...@anholt.net eric.anh...@intel.com signature.asc Description: This is a digitally signed message part -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H-- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] drm: Fix lock order reversal between mmap_sem and struct_mutex.
Eric Anholt wrote: On Fri, 2009-02-20 at 08:36 +0100, Peter Zijlstra wrote: On Thu, 2009-02-19 at 18:04 -0800, Eric Anholt wrote: On Thu, 2009-02-19 at 23:26 +0100, Peter Zijlstra wrote: On Thu, 2009-02-19 at 22:02 +0100, Thomas Hellstrom wrote: It looks to me like the driver preferred locking order is object_mutex (which happens to be the device global struct_mutex) mmap_sem offset_mutex. So if one could avoid using the struct_mutex for object bookkeeping (A separate lock) then vm_open() and vm_close() would adhere to that locking order as well, simply by not taking the struct_mutex at all. So only fault() remains, in which that locking order is reversed. Personally I think the trylock -reschedule-retry method with proper commenting is a good solution. It will be the _only_ place where locking order is reversed and it is done in a deadlock-safe manner. Note that fault() doesn't really fail, but requests a retry from user-space with rescheduling to give the process holding the struct_mutex time to release it. It doesn't do the reschedule -- need_resched() will check if the current task was marked to be scheduled away, furthermore yield based locking sucks chunks. Imagine what would happen if your faulting task was the highest RT prio task in the system, you'd end up with a life-lock. What's so very difficult about pulling the copy_*_user() out from under the locks? That we're expecting the data movement to occur while holding device state in place. For example, we write data through the GTT most of the time so we: lock struct_mutex pin the object to the GTT flushing caches as needed copy_from_user unpin object unlock struct_mutex So you cannot drop the lock once you've pinned the dst object? If I'm to pull the copy_from_user out, that means I have to: alloc temporary storage for each block of temp storage size: copy_from_user lock struct_mutex pin the object to the GTT flush caches as needed memcpy unpin object unlock struct_mutex At this point of introducing our third copy of the user's data in our hottest path, we should probably ditch the pwrite path entirely and go to user mapping of the objects for performance. Requiring user mapping (which has significant overhead) cuts the likelihood of moving from user-space object caching to kernel object caching in the future, which has the potential of saving steaming piles of memory. Or you could get_user_pages() to fault the user pages and pin them, and then do pagefault_disable() and use copy_from_user_inatomic or such, and release the pages again. I started poking at this today, since the get_user_pages sounded like the solution. Only then I noticed: when we unbind an existing object, we have to unmap_mapping_range to clear the clients' mappings to it in the GTT, which needs to happen while the struct lock (protecting the gtt structure and the gtt to object mappings) is held. So for fault we have mmap_sem held to struct mutex taken for poking at the gtt structure, and for unbind we have struct mutex held to mmap_sem taken to clear mappings. I don't think the mmap_sem is taken during unmap_mapping_rage() ? /Thomas -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] drm: Fix lock order reversal between mmap_sem and struct_mutex.
On Wed, 2009-02-25 at 00:15 -0800, Eric Anholt wrote: Or you could get_user_pages() to fault the user pages and pin them, and then do pagefault_disable() and use copy_from_user_inatomic or such, and release the pages again. I started poking at this today, since the get_user_pages sounded like the solution. Only then I noticed: when we unbind an existing object, we have to unmap_mapping_range to clear the clients' mappings to it in the GTT, which needs to happen while the struct lock (protecting the gtt structure and the gtt to object mappings) is held. So for fault we have mmap_sem held to struct mutex taken for poking at the gtt structure, and for unbind we have struct mutex held to mmap_sem taken to clear mappings. So it again comes down to the fact that you cannot pin a gtt object without also holding this struct_mutex? Normally such things are done by elevating a refcount so that both regular frees and reclaim gets delayed until you're done with the object. -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [Intel-gfx] [PATCH] i915: add page flipping ioctl
On Thursday, February 19, 2009 9:46:06 pm Zou, Nanhai wrote: +if ((pipe = flip_data-pipe) 1) { +DRM_ERROR(bad pipe\n); +return -EINVAL; +} pipe should be unsigned int, if it is int, this check should be if (pipe 1 || pipe 0) Yeah, fixed (the ioctl arg is already unsigned, so it should match). +spin_lock_irqsave(dev_priv-vblank_lock, flags); + +BEGIN_LP_RING(4); This could be sleep in atomic because BEGIN_LP_RING may sleep. Ok, I'll pull that bit out... but doing that introduces a small race. If we lose the race (the flip happens immediately and we get interrupted before adding the object to the vblank queue) the object will be stalled for one extra frame. +obj_priv = object_list[i]-driver_private; +if (i915_gem_flip_pending(object_list[i])) +wait_for_completion(obj_priv-vblank); I am wondering if this will block other clients execbuffer to run thus hurt their performance because struct_mutex is hold. Yeah, that's a good point. I'll see if we can drop it here and restart the execbuffer if that happens. Thanks for checking it out; new patch on its way soon. -- Jesse Barnes, Intel Open Source Technology Center -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [Intel-gfx] [PATCH] i915: add page flipping ioctl
On Friday, February 20, 2009 2:06:33 am Chris Wilson wrote: On Fri, 2009-02-20 at 13:46 +0800, Zou, Nanhai wrote: +struct drm_i915_gem_page_flip { + /** Handle of new front buffer */ Should this be handle of new front buffer or handle of the execbuf? I can't see how this can be an execbuf here. Do you mind elaborating? Anyway this reminded me that we want a buffer offset along with the handle. Yeah I'm not sure I understand that comment either; but an offset is easy enough to add. I suppose it should be an offset into the object, in case you want to flip between addresses within a large object? -- Jesse Barnes, Intel Open Source Technology Center -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Page flipping update
Here's the kernel, libdrm, mesa and xserver patches Im working with atm. These ones are untested (need to update the xf86-video-intel bits first, which is why they're not included here), but I wanted people to take a look and make sure things are looking ok. -- Jesse Barnes, Intel Open Source Technology Center -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] i915: page flipping support
This one still doesn't include a KMS version, but the rest of it should be nearly ready. I've taken Chris Nanhai's feedback from the last round and incorporated it, so we'll no longer block with the struct_mutex held at execbuffer time if a flip is pending, and the ring command submission has been pulled out of the spinlock, since that could have been bad (though it does introduce a harmless race). The basic idea is the same: a client calls the flip ioctl with a buffer object it would like to use as the new front buffer (it's up to the client to make sure any future drawing points at the right buffer; either the new front buffer in the case of X rendering, or the new back buffer in the case of new GL rendering from that client). Also in the non-KMS case, the client has to ensure that the new buffer is pinned, and that the old one is in the right mode for whatever is expected to happen with it following the flip. diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2d797ff..8868ad2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -829,6 +829,172 @@ static int i915_set_status_page(struct drm_device *dev, void *data, return 0; } +static int i915_pipe_to_plane(struct drm_device *dev, int pipe) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + u32 reg, pipe_mask; + + if (pipe == 0) + pipe_mask = DISPPLANE_SEL_PIPE_A; + else + pipe_mask = DISPPLANE_SEL_PIPE_B; + + pipe_mask |= DISPLAY_PLANE_ENABLE; + + reg = I915_READ(DSPACNTR); + if ((reg (DISPLAY_PLANE_ENABLE | DISPPLANE_SEL_PIPE_MASK)) == + pipe_mask) + return 0; + + reg = I915_READ(DSPBCNTR); + if ((reg (DISPLAY_PLANE_ENABLE | DISPPLANE_SEL_PIPE_MASK)) == + pipe_mask) + return 1; + + return -1; +} + +bool +i915_gem_flip_pending(struct drm_gem_object *obj) +{ + struct drm_device *dev = obj-dev; + drm_i915_private_t *dev_priv = dev-dev_private; + struct drm_i915_gem_object *obj_priv = obj-driver_private; + unsigned long flags; + bool pending = false; + + spin_lock_irqsave(dev_priv-vblank_lock, flags); + if (!list_empty(obj_priv-vblank_head)) + pending = true; + spin_unlock_irqrestore(dev_priv-vblank_lock, flags); + + return pending; +} + +static int i915_gem_page_flip(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_i915_gem_page_flip *flip_data = data; + drm_i915_private_t *dev_priv = dev-dev_private; + struct drm_gem_object *obj; + struct drm_i915_gem_object *obj_priv; + unsigned long flags; + uint32_t offset; + unsigned int pitch, pipe, plane, tiled; + int ret = 0; + RING_LOCALS; + + if (!(dev-driver-driver_features DRIVER_GEM)) + return -ENODEV; + + /* +* Reject unknown flags so future userspace knows what we (don't) +* support +*/ + if (flip_data-flags (~I915_PAGE_FLIP_WAIT)) { + DRM_ERROR(bad page flip flags\n); + return -EINVAL; + } + + if ((pipe = flip_data-pipe) 1) { + DRM_ERROR(bad pipe\n); + return -EINVAL; + } + + plane = i915_pipe_to_plane(dev, pipe); + if (plane 0) { + DRM_ERROR(bad pipe (no planes enabled?)\n); + return -EINVAL; + } + + obj = drm_gem_object_lookup(dev, file_priv, flip_data-handle); + if (obj == NULL) + return -EBADF; + + /* +* Make sure the new buffer is in bounds +* FIXME: should probably check against current mode as well +*/ + if (flip_data-offset = obj-size) { + DRM_ERROR(bad flip offset\n); + ret = -EINVAL; + goto out_unref; + } + + obj_priv = obj-driver_private; + + if (i915_gem_flip_pending(obj)) + wait_for_completion(obj_priv-vblank); + + mutex_lock(dev-struct_mutex); + if (obj_priv-tiling_mode != I915_TILING_NONE + obj_priv-tiling_mode != I915_TILING_X) { + DRM_ERROR(can only flip non-tiled or X tiled pages\n); + ret = -EINVAL; + goto out_unref; + } + +#if 0 + ret = i915_gem_object_pin(obj, 0); + if (ret) { + DRM_ERROR(failed to pin object for flip\n); + ret = -EBUSY; + goto out_unref; + } +#endif + /* +* Put the object in the GTT domain before the flip, +* since there may be outstanding rendering +*/ + i915_gem_object_set_to_gtt_domain(obj, 0); + + offset = obj_priv-gtt_offset + flip_data-offset; + + pitch = obj_priv-stride; + tiled = !!(obj_priv-tiling_mode == I915_TILING_X); + + BEGIN_LP_RING(4); +
[PATCH] libdrm: support page flipping on i915
diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h index 5456e91..a36bcf6 100644 --- a/shared-core/i915_drm.h +++ b/shared-core/i915_drm.h @@ -205,6 +205,7 @@ typedef struct drm_i915_sarea { #define DRM_I915_GEM_GET_TILING0x22 #define DRM_I915_GEM_GET_APERTURE 0x23 #define DRM_I915_GEM_MMAP_GTT 0x24 +#define DRM_I915_GEM_PAGE_FLIP 0x25 #define DRM_IOCTL_I915_INITDRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -769,4 +770,30 @@ struct drm_i915_gem_get_aperture { uint64_t aper_available_size; }; +#define I915_PAGE_FLIP_WAIT (10) /* block on page flip completion */ + +struct drm_i915_gem_page_flip { + /** Handle of new front buffer */ + uint32_t handle; + + /** Offset into object to flip to */ + uint64_t offset; + + /** +* page flip flags (wait on flip only for now) +*/ + uint32_t flags; + + /** +* pipe to flip +*/ + uint32_t pipe; + + /** +* screen dimensions for flip +*/ + uint32_t x; + uint32_t y; +}; + #endif /* _I915_DRM_H_ */ -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] mesa/intel: support for DRI2 swapbuffers
The DRI2 protocol and support bits for Mesa are pretty straightfoward. But I still need to port this forward to the new flush hook code, since at swapbuffers we need to make sure everything is flushed. diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 27cc1be..5a60426 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -670,6 +670,9 @@ struct __DRIdri2ExtensionRec { __DRIcontext *shared, void *loaderPrivate); +void (*setBuffers)(__DRIdrawable *drawable, + __DRIbuffer *buffers, + int count); }; #endif diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c index f967432..564bd4b 100644 --- a/src/glx/x11/dri2.c +++ b/src/glx/x11/dri2.c @@ -299,3 +299,52 @@ void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, UnlockDisplay(dpy); SyncHandle(); } + +DRI2Buffer *DRI2SwapBuffers(Display *dpy, XID drawable, int *count) +{ +XExtDisplayInfo *info = DRI2FindDisplay(dpy); +xDRI2SwapBuffersReq *req; +xDRI2SwapBuffersReply rep; +xDRI2Buffer repBuffer; +DRI2Buffer *buffers; +int i; + +XextCheckExtension (dpy, info, dri2ExtensionName, False); + +LockDisplay(dpy); +GetReq(DRI2SwapBuffers, req); +req-reqType = info-codes-major_opcode; +req-dri2ReqType = X_DRI2SwapBuffers; +req-drawable = drawable; + +if (!_XReply(dpy, (xReply *)rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return NULL; +} + +/* We expect a new front back in return */ +buffers = Xmalloc(rep.count * sizeof(DRI2Buffer)); +if (buffers == NULL) { + _XEatData(dpy, rep.count * sizeof repBuffer); + UnlockDisplay(dpy); + SyncHandle(); + return NULL; +} + +for (i = 0; i rep.count; i++) { + _XReadPad(dpy, (char *) repBuffer, sizeof repBuffer); + buffers[i].attachment = repBuffer.attachment; + buffers[i].name = repBuffer.name; + buffers[i].pitch = repBuffer.pitch; + buffers[i].cpp = repBuffer.cpp; + buffers[i].flags = repBuffer.flags; +} + +*count = rep.count; + +UnlockDisplay(dpy); +SyncHandle(); + +return buffers; +} diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h index 356c6bc..83dfaf6 100644 --- a/src/glx/x11/dri2.h +++ b/src/glx/x11/dri2.h @@ -67,4 +67,7 @@ extern void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, CARD32 dest, CARD32 src); +extern DRI2Buffer * +DRI2SwapBuffers(Display *dpy, XID drawable, int *count); + #endif diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index b878f05..d652f13 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -61,6 +61,8 @@ struct __GLXDRIdisplayPrivateRec { int driMinor; int driPatch; +int swapAvailable; + unsigned long configureSeqno; Bool (*oldConfigProc)(Display *, XEvent *, xEvent *); }; @@ -210,8 +212,34 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, static void dri2SwapBuffers(__GLXDRIdrawable *pdraw) { __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; +__GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)priv-base.psc-dpy; +__GLXscreenConfigs *psc = pdraw-psc; +DRI2Buffer *buffers; +int i, j, count; + +/* Old servers can't handle swapbuffers */ +if (!pdp-swapAvailable) + return dri2CopySubBuffer(pdraw, 0, 0, priv-width, priv-height); + +buffers = DRI2SwapBuffers(pdraw-psc-dpy, pdraw-drawable, count); +if (buffers == NULL) + return dri2CopySubBuffer(pdraw, 0, 0, priv-width, priv-height); + +/* Update our buffer list with what was returned */ +for (j = 0; j count; j++) { + for (i = 0; i priv-bufferCount; i++) { + if (priv-buffers[i].attachment == buffers[j].attachment) { + priv-buffers[i].name = buffers[j].name; + priv-buffers[i].pitch = buffers[j].pitch; + priv-buffers[i].cpp = buffers[j].cpp; + priv-buffers[i].flags = buffers[j].flags; + } + } +} -dri2CopySubBuffer(pdraw, 0, 0, priv-width, priv-height); +(*psc-dri2-setBuffers)(pdraw-driDrawable, priv-buffers, count); + +Xfree(buffers); } static void dri2DestroyScreen(__GLXscreenConfigs *psc) @@ -442,6 +470,9 @@ _X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy) pdp-driPatch = 0; pdp-configureSeqno = 0; +pdp-swapAvailable = 0; +if (pdp-driMinor = 1) + pdp-swapAvailable = 1; pdp-base.destroyDisplay = dri2DestroyDisplay; pdp-base.createScreen = dri2CreateScreen; diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index ae79055..75afc45 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++
[PATCH] xserver: support DRI2 swapbuffers
Just realized I still need to check whether the driver supports swapbuffers, if not we should fall back to copyarea. Other than that it's pretty simple. diff --git a/glx/glxdri2.c b/glx/glxdri2.c index 4e76c71..42a596e 100644 --- a/glx/glxdri2.c +++ b/glx/glxdri2.c @@ -131,10 +131,27 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *drawable, static GLboolean __glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) { -__GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; +__GLXDRIdrawable *priv = (__GLXDRIdrawable *) drawable; +DRI2BufferPtr buffers; +int i, j, count; + +buffers = DRI2SwapBuffers(drawable-pDraw, count); +if (!buffers) + return FALSE; + +/* Update the front back buffer objects */ +for (j = 0; j count; j++) { + for (i = 0; i priv-count; i++) { + if (priv-buffers[i].attachment == buffers[j].attachment) { + priv-buffers[i].name = buffers[j].name; + priv-buffers[i].pitch = buffers[j].pitch; + priv-buffers[i].cpp = buffers[j].cpp; + priv-buffers[i].flags = buffers[j].flags; + } + } +} -__glXDRIdrawableCopySubBuffer(drawable, 0, 0, - private-width, private-height); +xfree(buffers); return TRUE; } diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 0f2e24b..2281d44 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -66,6 +66,7 @@ typedef struct _DRI2Screen { DRI2CreateBuffersProcPtrCreateBuffers; DRI2DestroyBuffersProcPtr DestroyBuffers; DRI2CopyRegionProcPtr CopyRegion; +DRI2SwapBuffersProcPtr SwapBuffers; HandleExposuresProcPtr HandleExposures; } DRI2ScreenRec, *DRI2ScreenPtr; @@ -188,6 +189,30 @@ DRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion, return Success; } +DRI2BufferPtr +DRI2SwapBuffers(DrawablePtr pDraw, int *reply_count) +{ +DRI2ScreenPtr ds = DRI2GetScreen(pDraw-pScreen); +DRI2DrawablePtr pPriv; +DRI2BufferPtr buffers; + +pPriv = DRI2GetDrawable(pDraw); +if (pPriv == NULL) + return NULL; + +/* Driver will give us a new set of buffers, so free the old ones */ +buffers = (*ds-SwapBuffers)(pDraw, pPriv-buffers, pPriv-bufferCount); +if (!buffers) + return NULL; + +(*ds-DestroyBuffers)(pDraw, pPriv-buffers, pPriv-bufferCount); +pPriv-buffers = buffers; + +*reply_count = pPriv-bufferCount; + +return buffers; +} + void DRI2DestroyDrawable(DrawablePtr pDraw) { @@ -264,6 +289,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) ds-CreateBuffers = info-CreateBuffers; ds-DestroyBuffers = info-DestroyBuffers; ds-CopyRegion = info-CopyRegion; +ds-SwapBuffers= info-SwapBuffers; dixSetPrivate(pScreen-devPrivates, dri2ScreenPrivateKey, ds); diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index 5e7fd65..8cb9e94 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -54,6 +54,9 @@ typedef void (*DRI2CopyRegionProcPtr)(DrawablePtr pDraw, RegionPtr pRegion, DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer); +typedef DRI2BufferPtr (*DRI2SwapBuffersProcPtr)(DrawablePtr pDraw, + DRI2BufferPtr buffers, + int count); typedef void (*DRI2WaitProcPtr)(WindowPtr pWin, unsigned int sequence); @@ -67,6 +70,7 @@ typedef struct { DRI2CreateBuffersProcPtr CreateBuffers; DRI2DestroyBuffersProcPtr DestroyBuffers; DRI2CopyRegionProcPtr CopyRegion; +DRI2SwapBuffersProcPtr SwapBuffers; DRI2WaitProcPtrWait; } DRI2InfoRec, *DRI2InfoPtr; @@ -100,4 +104,6 @@ int DRI2CopyRegion(DrawablePtr pDraw, unsigned int dest, unsigned int src); +DRI2BufferPtr DRI2SwapBuffers(DrawablePtr pDraw, int *count); + #endif diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index 0a1dce4..bd51f47 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -269,6 +269,45 @@ ProcDRI2CopyRegion(ClientPtr client) } static int +ProcDRI2SwapBuffers(ClientPtr client) +{ +REQUEST(xDRI2SwapBuffersReq); +xDRI2SwapBuffersReply rep; +DrawablePtr pDrawable; +DRI2BufferPtr buffers; +xDRI2Buffer buffer; +int status; +int i, count; + +REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq); + +if (!validDrawable(client, stuff-drawable, pDrawable, status)) + return status; + +buffers = DRI2SwapBuffers(pDrawable, count); +if (!buffers) { + status = BadAlloc; + return status; +} + +rep.type = X_Reply;
[PATCH] dri2proto: support buffer swaps
Protocol documentation and support for the new buffer swap request. diff --git a/dri2proto.h b/dri2proto.h index dc3f2d1..6f5ddf0 100644 --- a/dri2proto.h +++ b/dri2proto.h @@ -35,7 +35,7 @@ #define DRI2_NAME DRI2 #define DRI2_MAJOR 1 -#define DRI2_MINOR 0 +#define DRI2_MINOR 1 #define DRI2NumberErrors 0 #define DRI2NumberEvents 0 @@ -48,6 +48,7 @@ #define X_DRI2DestroyDrawable 4 #define X_DRI2GetBuffers 5 #define X_DRI2CopyRegion 6 +#define X_DRI2SwapBuffers 7 typedef struct { CARD32 attachment B32; @@ -190,4 +191,26 @@ typedef struct { } xDRI2CopyRegionReply; #define sz_xDRI2CopyRegionReply32 +typedef struct { +CARD8 reqType; +CARD8 dri2ReqType; +CARD16 length B16; +CARD32 drawable B32; +} xDRI2SwapBuffersReq; +#define sz_xDRI2SwapBuffersReq 8 + +typedef struct { +BYTEtype; /* X_Reply */ +BYTEpad1; +CARD16 sequenceNumber B16; +CARD32 length B32; +CARD32 count B32; +CARD32 pad3 B32; +CARD32 pad4 B32; +CARD32 pad5 B32; +CARD32 pad6 B32; +CARD32 pad7 B32; +} xDRI2SwapBuffersReply; +#define sz_xDRI2SwapBuffersReply 32 + #endif diff --git a/dri2proto.txt b/dri2proto.txt index 106f8d8..30a2157 100644 --- a/dri2proto.txt +++ b/dri2proto.txt @@ -105,6 +105,11 @@ DRI2 implementation of direct rendering GLX, should use these enty points to copy contents back and forth to as necessary to ensure consistent rendering. +The client may also use the DRI2SwapBuffers function to request a swap +of the front and back buffers. If the display server supports it, this +operation may be preferred, since it may be easier and/or more performant +for the server to perform a simple buffer swap rather than a blit. + ⚙ ⚙ ⚙ ⚙ ⚙ ⚙ @@ -280,6 +285,21 @@ The name of this extension is DRI2. the server has seen the request before proceeding with rendering the next frame. +┌─── +DRI2SwapBuffers + drawable: DRAWABLE + ▶ + buffers: LISTofDRI2BUFFER +└─── + Errors: Window + + Schedule a swap of the front and back buffers with the display + server. + + In reply, the display server is expected to provide new front + and back buffers to the client following this request. The + display server should process this request asynchronously + if possible, to prevent the client from blocking. ⚙ ⚙ ⚙ ⚙ ⚙ ⚙ @@ -474,6 +494,27 @@ A.2 Protocol Requests 24 unused └─── +┌─── +DRI2SwapBuffers + 1 CARD8 major opcode + 1 7 DRI2 opcode + 2 8 length + 4 DRAWABLEdrawable + ▶ + 1 1 Reply +1 unused + 2 CARD16 sequence number + 4 0 reply length + 4 CARD32 buffer count + 4 CARD32 unused + 4 CARD32 unused + 4 CARD32 unused + 4 CARD32 unused + 4 CARD32 unused + 4 CARD32 unused + 5n LISTofDRI2BUFFERbuffers +└─── + A.3 Protocol Events -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[Bug 12705] X200: Brightness broken since 2.6.29-rc4-58-g4c098bc
http://bugzilla.kernel.org/show_bug.cgi?id=12705 --- Comment #5 from r...@sisk.pl 2009-02-25 15:08 --- On Tuesday 24 February 2009, Nico Schottelius wrote: Still existing. Rafael J. Wysocki [Mon, Feb 23, 2009 at 10:48:13PM +0100]: This message has been generated automatically as a part of a report of recent regressions. The following bug entry is on the current list of known regressions from 2.6.28. Please verify if it still should be listed and let me know (either way). Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=12705 Subject : X200: Brightness broken since 2.6.29-rc4-58-g4c098bc -- Configure bugmail: http://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug, or are watching the assignee. -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[Bug 12613] [Suspend regression][DRM, RADEON]
http://bugzilla.kernel.org/show_bug.cgi?id=12613 r...@sisk.pl changed: What|Removed |Added Status|NEW |CLOSED Resolution||CODE_FIX --- Comment #8 from r...@sisk.pl 2009-02-25 14:56 --- Fixed by: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=3d16118dc825a654043dfe3e14371fdf2976994d -- Configure bugmail: http://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug, or are watching the assignee. -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[Bug 12419] possible circular locking dependency on i915 dma
http://bugzilla.kernel.org/show_bug.cgi?id=12419 --- Comment #7 from r...@sisk.pl 2009-02-25 14:54 --- On Tuesday 24 February 2009, Wang Chen wrote: Rafael J. Wysocki said the following on 2009-2-24 5:48: This message has been generated automatically as a part of a report of recent regressions. The following bug entry is on the current list of known regressions from 2.6.28. Please verify if it still should be listed and let me know (either way). Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=12419 Subject : possible circular locking dependency on i915 dma Submitter : Wang Chen wangc...@cn.fujitsu.com Date: 2009-01-08 14:11 (47 days old) First-Bad-Commit: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=546b0974c39657017407c86fe79811100b60700d References : http://marc.info/?l=linux-kernelm=123142399720125w=4 not changed. === [ INFO: possible circular locking dependency detected ] 2.6.29-rc6-default #165 --- X/3940 is trying to acquire lock: (mm-mmap_sem){}, at: [c0168e97] might_fault+0x42/0x7e but task is already holding lock: (dev-struct_mutex){--..}, at: [eeb76fed] i915_cmdbuffer+0xf4/0x411 [i915] which lock already depends on the new lock. the existing dependency chain (in reverse order) is: - #2 (dev-struct_mutex){--..}: [c013791a] validate_chain+0x8be/0xbb5 [c0138280] __lock_acquire+0x66f/0x6f9 [c0138365] lock_acquire+0x5b/0x77 [c02e56fe] mutex_lock_nested+0xdb/0x244 [eeb5b03e] drm_vm_open+0x25/0x37 [drm] [c011a8b3] dup_mm+0x247/0x2f2 [c011b312] copy_process+0x98c/0xfeb [c011bac7] do_fork+0x120/0x29c [c01016be] sys_clone+0x25/0x2a [c0102cdd] sysenter_do_call+0x12/0x31 [] 0x - #1 (mm-mmap_sem/1){--..}: [c013791a] validate_chain+0x8be/0xbb5 [c0138280] __lock_acquire+0x66f/0x6f9 [c0138365] lock_acquire+0x5b/0x77 [c012e6f6] down_write_nested+0x32/0x4f [c011a711] dup_mm+0xa5/0x2f2 [c011b312] copy_process+0x98c/0xfeb [c011bac7] do_fork+0x120/0x29c [c01016be] sys_clone+0x25/0x2a [c0102cdd] sysenter_do_call+0x12/0x31 [] 0x - #0 (mm-mmap_sem){}: [c0137625] validate_chain+0x5c9/0xbb5 [c0138280] __lock_acquire+0x66f/0x6f9 [c0138365] lock_acquire+0x5b/0x77 [c0168eb4] might_fault+0x5f/0x7e [eeb76d0a] i915_emit_box+0x1d/0x20c [i915] [eeb7705e] i915_cmdbuffer+0x165/0x411 [i915] [eeb5685b] drm_ioctl+0x1a6/0x21b [drm] [c0182b29] vfs_ioctl+0x3d/0x50 [c0183029] do_vfs_ioctl+0x41b/0x483 [c01830d1] sys_ioctl+0x40/0x5a [c0102cdd] sysenter_do_call+0x12/0x31 [] 0x -- Configure bugmail: http://bugzilla.kernel.org/userprefs.cgi?tab=email --- You are receiving this mail because: --- You are the assignee for the bug, or are watching the assignee. -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm/ati_pcigart: use memset_io to reset the memory
From: Dave Airlie airl...@redhat.com Also don't setup pci_gart if we aren't going to need it. Signed-off-by: Dave Airlie airl...@redhat.com --- drivers/gpu/drm/ati_pcigart.c |7 +++ 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c index 4d86a62..628eae3 100644 --- a/drivers/gpu/drm/ati_pcigart.c +++ b/drivers/gpu/drm/ati_pcigart.c @@ -99,7 +99,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga struct drm_sg_mem *entry = dev-sg; void *address = NULL; unsigned long pages; - u32 *pci_gart, page_base, gart_idx; + u32 *pci_gart = NULL, page_base, gart_idx; dma_addr_t bus_address = 0; int i, j, ret = 0; int max_ati_pages, max_real_pages; @@ -118,6 +118,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga goto done; } + pci_gart = gart_info-table_handle-vaddr; address = gart_info-table_handle-vaddr; bus_address = gart_info-table_handle-busaddr; } else { @@ -128,7 +129,6 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga (unsigned long)address); } - pci_gart = (u32 *) address; max_ati_pages = (gart_info-table_size / sizeof(u32)); max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); @@ -138,8 +138,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga if (gart_info-gart_table_location == DRM_ATI_GART_MAIN) { memset(pci_gart, 0, max_ati_pages * sizeof(u32)); } else { - for (gart_idx = 0; gart_idx max_ati_pages; gart_idx++) - DRM_WRITE32(map, gart_idx * sizeof(u32), 0); + memset_io((void __iomem *)map-handle, 0, max_ati_pages * sizeof(u32)); } gart_idx = 0; -- 1.6.0.4 -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm: add DRM_READ/WRITE64 wrappers around readq/writeq.
From: Dave Airlie airl...@redhat.com The readq/writeq stuff is from Dave Miller, and he warns users to be careful about using these. Plans are only r600 to use it so far. Signed-off-by: Dave Airlie airl...@redhat.com --- include/drm/drm_os_linux.h | 19 +++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/include/drm/drm_os_linux.h b/include/drm/drm_os_linux.h index 8dbd257..013551d 100644 --- a/include/drm/drm_os_linux.h +++ b/include/drm/drm_os_linux.h @@ -6,6 +6,19 @@ #include linux/interrupt.h /* For task queue support */ #include linux/delay.h +#ifndef readq +static u64 readq(void __iomem *reg) +{ + return ((u64) readl(reg)) | (((u64) readl(reg + 4UL)) 32); +} + +static void writeq(u64 val, void __iomem *reg) +{ + writel(val 0x, reg); + writel(val 32, reg + 0x4UL); +} +#endif + /** Current process ID */ #define DRM_CURRENTPID task_pid_nr(current) #define DRM_SUSER(p) capable(CAP_SYS_ADMIN) @@ -23,6 +36,12 @@ /** Write a dword into a MMIO region */ #define DRM_WRITE32(map, offset, val) writel(val, ((void __iomem *)(map)-handle) + (offset)) /** Read memory barrier */ + +/** Read a qword from a MMIO region - be careful using these unless you really understand them */ +#define DRM_READ64(map, offset)readq(((void __iomem *)(map)-handle) + (offset)) +/** Write a qword into a MMIO region */ +#define DRM_WRITE64(map, offset, val) writeq(val, ((void __iomem *)(map)-handle) + (offset)) + #define DRM_READMEMORYBARRIER()rmb() /** Write memory barrier */ #define DRM_WRITEMEMORYBARRIER() wmb() -- 1.6.0.4 -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm/r600: fixup r600 gart table accessor like ati_pcigart.c
From: Dave Airlie airl...@redhat.com This attempts to fixup the r600 GART accessors so they work on other arches. Signed-off-by: Dave Airlie airl...@redhat.com --- drivers/gpu/drm/radeon/r600_cp.c | 23 +-- 1 files changed, 13 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 0143a14..54ea867 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c @@ -142,23 +142,25 @@ int r600_page_table_init(struct drm_device *dev) { drm_radeon_private_t *dev_priv = dev-dev_private; struct drm_ati_pcigart_info *gart_info = dev_priv-gart_info; + struct drm_local_map *map = gart_info-mapping; struct drm_sg_mem *entry = dev-sg; int ret = 0; int i, j; - int max_pages, pages; - u64 *pci_gart, page_base; + int pages; + u64 page_base; dma_addr_t entry_addr; + int max_ati_pages, max_real_pages, gart_idx; /* okay page table is available - lets rock */ + max_ati_pages = (gart_info-table_size / sizeof(u64)); + max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); - /* PTEs are 64-bits */ - pci_gart = (u64 *)gart_info-addr; - - max_pages = (gart_info-table_size / sizeof(u64)); - pages = (entry-pages = max_pages) ? entry-pages : max_pages; + pages = (entry-pages = max_real_pages) ? + entry-pages : max_real_pages; - memset(pci_gart, 0, max_pages * sizeof(u64)); + memset_io((void __iomem *)map-handle, 0, max_ati_pages * sizeof(u64)); + gart_idx = 0; for (i = 0; i pages; i++) { entry-busaddr[i] = pci_map_single(dev-pdev, page_address(entry- @@ -176,12 +178,13 @@ int r600_page_table_init(struct drm_device *dev) page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED; page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE; - *pci_gart = page_base; + DRM_WRITE64(map, gart_idx * sizeof(u64), page_base); + + gart_idx++; if ((i % 128) == 0) DRM_DEBUG(page entry %d: 0x%016llx\n, i, (unsigned long long)page_base); - pci_gart++; entry_addr += ATI_PCIGART_PAGE_SIZE; } } -- 1.6.0.4 -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm/r600: fix rptr address along lines of previous fixes to radeon.
From: Dave Airlie airl...@redhat.com Signed-off-by: Dave Airlie airl...@redhat.com --- drivers/gpu/drm/radeon/r600_cp.c | 14 -- 1 files changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c index 54ea867..37249b2 100644 --- a/drivers/gpu/drm/radeon/r600_cp.c +++ b/drivers/gpu/drm/radeon/r600_cp.c @@ -1689,18 +1689,12 @@ static void r600_cp_init_ring_buffer(struct drm_device *dev, } else #endif { - struct drm_sg_mem *entry = dev-sg; - unsigned long tmp_ofs, page_ofs; - - tmp_ofs = dev_priv-ring_rptr-offset - - (unsigned long)dev-sg-virtual; - page_ofs = tmp_ofs PAGE_SHIFT; + RADEON_WRITE(R600_CP_RB_RPTR_ADDR, +dev_priv-ring_rptr-offset +- ((unsigned long) dev-sg-virtual) ++ dev_priv-gart_vm_start); - RADEON_WRITE(R600_CP_RB_RPTR_ADDR, entry-busaddr[page_ofs] 8); RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI, 0); - DRM_DEBUG(ring rptr: offset=0x%08lx handle=0x%08lx\n, - (unsigned long)entry-busaddr[page_ofs], - entry-handle + tmp_ofs); } #ifdef __BIG_ENDIAN -- 1.6.0.4 -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [Intel-gfx] [PATCH] i915: add page flipping ioctl
On Wed, 2009-02-25 at 11:42 -0800, Jesse Barnes wrote: Ok, I'll pull that bit out... but doing that introduces a small race. If we lose the race (the flip happens immediately and we get interrupted before adding the object to the vblank queue) the object will be stalled for one extra frame. So wait for space, grab the lock, check for space again, and retry if you fail, right? -- keith.pack...@intel.com signature.asc Description: This is a digitally signed message part -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise -Strategies to boost innovation and cut costs with open source participation -Receive a $600 discount off the registration fee with the source code: SFAD http://p.sf.net/sfu/XcvMzF8H-- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel