Re: [PATCH 1/6] drivers/dri/common: A few dri2 functions are not actually DRI2 specific
On Thu, Oct 31, 2013 at 04:13:11PM -0700, Keith Packard wrote: This just renames them so that they can be used with the DRI3 extension without causing too much confusion. Signed-off-by: Keith Packard kei...@keithp.com --- src/mesa/drivers/dri/common/dri_util.c | 50 +- 1 file changed, 25 insertions(+), 25 deletions(-) Reviewed-by: Kristian Høgsberg k...@bitplanet.net diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index c28b0fc..539fb4b 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -291,13 +291,13 @@ validate_context_version(__DRIscreen *screen, /*@{*/ static __DRIcontext * -dri2CreateContextAttribs(__DRIscreen *screen, int api, - const __DRIconfig *config, - __DRIcontext *shared, - unsigned num_attribs, - const uint32_t *attribs, - unsigned *error, - void *data) +driCreateContextAttribs(__DRIscreen *screen, int api, +const __DRIconfig *config, +__DRIcontext *shared, +unsigned num_attribs, +const uint32_t *attribs, +unsigned *error, +void *data) { __DRIcontext *context; const struct gl_config *modes = (config != NULL) ? config-modes : NULL; @@ -442,22 +442,22 @@ dri2CreateContextAttribs(__DRIscreen *screen, int api, } static __DRIcontext * -dri2CreateNewContextForAPI(__DRIscreen *screen, int api, -const __DRIconfig *config, -__DRIcontext *shared, void *data) +driCreateNewContextForAPI(__DRIscreen *screen, int api, + const __DRIconfig *config, + __DRIcontext *shared, void *data) { unsigned error; -return dri2CreateContextAttribs(screen, api, config, shared, 0, NULL, - error, data); +return driCreateContextAttribs(screen, api, config, shared, 0, NULL, + error, data); } static __DRIcontext * -dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config, - __DRIcontext *shared, void *data) +driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config, +__DRIcontext *shared, void *data) { -return dri2CreateNewContextForAPI(screen, __DRI_API_OPENGL, - config, shared, data); +return driCreateNewContextForAPI(screen, __DRI_API_OPENGL, + config, shared, data); } /** @@ -609,9 +609,9 @@ static void dri_put_drawable(__DRIdrawable *pdp) } static __DRIdrawable * -dri2CreateNewDrawable(__DRIscreen *screen, - const __DRIconfig *config, - void *data) +driCreateNewDrawable(__DRIscreen *screen, + const __DRIconfig *config, + void *data) { __DRIdrawable *pdraw; @@ -698,7 +698,7 @@ dri2ConfigQueryf(__DRIscreen *screen, const char *var, GLfloat *val) } static unsigned int -dri2GetAPIMask(__DRIscreen *screen) +driGetAPIMask(__DRIscreen *screen) { return screen-api_mask; } @@ -741,13 +741,13 @@ const __DRIdri2Extension driDRI2Extension = { .base = { __DRI_DRI2, 4 }, .createNewScreen= dri2CreateNewScreen, -.createNewDrawable = dri2CreateNewDrawable, -.createNewContext = dri2CreateNewContext, -.getAPIMask = dri2GetAPIMask, -.createNewContextForAPI = dri2CreateNewContextForAPI, +.createNewDrawable = driCreateNewDrawable, +.createNewContext = driCreateNewContext, +.getAPIMask = driGetAPIMask, +.createNewContextForAPI = driCreateNewContextForAPI, .allocateBuffer = dri2AllocateBuffer, .releaseBuffer = dri2ReleaseBuffer, -.createContextAttribs = dri2CreateContextAttribs, +.createContextAttribs = driCreateContextAttribs .createNewScreen2 = dri2CreateNewScreen2, }; -- 1.8.4.2 -- Android is increasing in popularity, but the open development platform that developers love is also attractive to malware creators. Download this white paper to learn more about secure code signing practices that can help keep Android apps secure. http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel ___ dri
Re: [PATCH 2/6] dri/intel: Split out DRI2 buffer update code to separate function
On Thu, Oct 31, 2013 at 04:13:12PM -0700, Keith Packard wrote: Make an easy place to splice in a DRI3 version of this function Signed-off-by: Keith Packard kei...@keithp.com --- src/mesa/drivers/dri/i915/intel_context.c | 90 +-- src/mesa/drivers/dri/i965/brw_context.c | 22 ++-- 2 files changed, 68 insertions(+), 44 deletions(-) Reviewed-by: Kristian Høgsberg k...@bitplanet.net diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index 2748514..1798bc7 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -133,15 +133,58 @@ intel_process_dri2_buffer(struct intel_context *intel, struct intel_renderbuffer *rb, const char *buffer_name); -void -intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) +static void +intel_update_dri2_buffers(struct intel_context *intel, __DRIdrawable *drawable) { - struct gl_framebuffer *fb = drawable-driverPrivate; - struct intel_renderbuffer *rb; - struct intel_context *intel = context-driverPrivate; __DRIbuffer *buffers = NULL; int i, count; const char *region_name; + struct intel_renderbuffer *rb; + struct gl_framebuffer *fb = drawable-driverPrivate; + + intel_query_dri2_buffers(intel, drawable, buffers, count); + + if (buffers == NULL) + return; + + for (i = 0; i count; i++) { + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); + region_name = dri2 front buffer; + break; + + case __DRI_BUFFER_FAKE_FRONT_LEFT: + rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); + region_name = dri2 fake front buffer; + break; + + case __DRI_BUFFER_BACK_LEFT: + rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT); + region_name = dri2 back buffer; + break; + + case __DRI_BUFFER_DEPTH: + case __DRI_BUFFER_HIZ: + case __DRI_BUFFER_DEPTH_STENCIL: + case __DRI_BUFFER_STENCIL: + case __DRI_BUFFER_ACCUM: + default: + fprintf(stderr, + unhandled buffer attach event, attachment type %d\n, + buffers[i].attachment); + return; + } + + intel_process_dri2_buffer(intel, drawable, buffers[i], rb, region_name); + } +} + +void +intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) +{ + struct intel_context *intel = context-driverPrivate; + __DRIscreen *screen = intel-intelScreen-driScrnPriv; /* Set this up front, so that in case our buffers get invalidated * while we're getting new buffers, we don't clobber the stamp and @@ -151,42 +194,7 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) if (unlikely(INTEL_DEBUG DEBUG_DRI)) fprintf(stderr, enter %s, drawable %p\n, __func__, drawable); - intel_query_dri2_buffers(intel, drawable, buffers, count); - - if (buffers == NULL) - return; - - for (i = 0; i count; i++) { - switch (buffers[i].attachment) { - case __DRI_BUFFER_FRONT_LEFT: -rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); -region_name = dri2 front buffer; -break; - - case __DRI_BUFFER_FAKE_FRONT_LEFT: -rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); -region_name = dri2 fake front buffer; -break; - - case __DRI_BUFFER_BACK_LEFT: -rb = intel_get_renderbuffer(fb, BUFFER_BACK_LEFT); -region_name = dri2 back buffer; -break; - - case __DRI_BUFFER_DEPTH: - case __DRI_BUFFER_HIZ: - case __DRI_BUFFER_DEPTH_STENCIL: - case __DRI_BUFFER_STENCIL: - case __DRI_BUFFER_ACCUM: - default: -fprintf(stderr, -unhandled buffer attach event, attachment type %d\n, -buffers[i].attachment); -return; - } - - intel_process_dri2_buffer(intel, drawable, buffers[i], rb, region_name); - } + intel_update_dri2_buffers(intel, drawable); driUpdateFramebufferSize(intel-ctx, drawable); } diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 38147e9..c213b31 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -929,12 +929,11 @@ intel_process_dri2_buffer(struct brw_context *brw, struct intel_renderbuffer *rb, const char *buffer_name); -void -intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) +static void +intel_update_dri2_buffers(struct brw_context *brw, __DRIdrawable *drawable) { struct gl_framebuffer *fb = drawable-driverPrivate; struct
Re: [Intel-gfx] [PATCH 2/7] drm: delay vblank cleanup until after driver unload
On Fri, Mar 26, 2010 at 7:07 PM, Jesse Barnes jbar...@virtuousgeek.org wrote: Drivers may use vblank calls now (e.g. drm_vblank_off) in their unload paths, so don't clean up the vblank related structures until after driver unload. I haven't tested this specific patch on a recent DRM, but I made the same patch a while ago, and it fixed module unload for me. I sent it to the list and it fell through the cracks, because vblank is hard or something. Reviewed-by: Kristian Høgsberg k...@bitplanet.net Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- drivers/gpu/drm/drm_stub.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index ad73e14..543e79c 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -515,8 +515,6 @@ void drm_put_dev(struct drm_device *dev) } driver = dev-driver; - drm_vblank_cleanup(dev); - drm_lastclose(dev); if (drm_core_has_MTRR(dev) drm_core_has_AGP(dev) @@ -536,6 +534,8 @@ void drm_put_dev(struct drm_device *dev) dev-agp = NULL; } + drm_vblank_cleanup(dev); + list_for_each_entry_safe(r_list, list_temp, dev-maplist, head) drm_rmmap(dev, r_list-map); drm_ht_remove(dev-map_hash); -- 1.6.1.3 ___ Intel-gfx mailing list intel-...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Download Intel#174; Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH 2/3] libdrm_nouveau requires libdrm
On Fri, Feb 26, 2010 at 1:07 PM, Julien Cristau jcris...@debian.org wrote: nouveau_drmif.h includes xf86drm.h. If it's a source level dependency it should be a regular Requires: in the .pc. Requires.private: is only for private libraries you link to but don't expose their API in your header files. The idea is (AFAIK) that you can ask pkg-config to list all libraries to link to for static linking, in which case pkg-config needs a way to find all needed libraries. It even looks like Requires.private has been obsoleted by Libs.private in recent pkg-config. Signed-off-by: Julien Cristau jcris...@debian.org --- nouveau/libdrm_nouveau.pc.in | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/nouveau/libdrm_nouveau.pc.in b/nouveau/libdrm_nouveau.pc.in index 7ef49e5..6ae6287 100644 --- a/nouveau/libdrm_nouveau.pc.in +++ b/nouveau/libdrm_nouveau.pc.in @@ -8,3 +8,4 @@ Description: Userspace interface to nouveau kernel DRM services Version: 0.6 Libs: -L${libdir} -ldrm_nouveau Cflags: -I${includedir} -I${includedir}/drm -I${includedir}/nouveau +Requires.private: libdrm -- 1.6.6.1 -- Download Intel#174; Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel -- Download Intel#174; Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH 2/3] libdrm_nouveau requires libdrm
2010/2/26 Julien Cristau jcris...@debian.org: On Fri, Feb 26, 2010 at 13:38:59 -0500, Kristian Høgsberg wrote: On Fri, Feb 26, 2010 at 1:07 PM, Julien Cristau jcris...@debian.org wrote: nouveau_drmif.h includes xf86drm.h. If it's a source level dependency it should be a regular Requires: in the .pc. Requires.private: is only for private libraries you link to but don't expose their API in your header files. The idea is (AFAIK) that you can ask pkg-config to list all libraries to link to for static linking, in which case pkg-config needs a way to find all needed libraries. It even looks like Requires.private has been obsoleted by Libs.private in recent pkg-config. That's not what the pkg-config maintainer says... http://err.no/personal/blog/2008/Mar/25 Using Requires.private lets us get the necessary cflags, but avoids linking to the library if not using --static. Oh, I see. Well it sounds like at some point Requires.private did what I thought it did. Thanks for the pointer. Kristian -- Download Intel#174; Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Some fixes for dri2proto.txt
Thanks, applied. On Tue, Feb 16, 2010 at 5:03 PM, Mike Stroyan m...@lunarg.com wrote: In studying dri2proto.txt I noticed that it has several places that don't mention the events that have been added. I also noticed a couple of typos and a reference to a 'group' field that does not exist. Here are patches for those issues. I am unsure of the padding in the DRI2_InvalidateBuffers event. -- Mike Stroyan - Software Architect LunarG, Inc. - The Graphics Experts Cell: (970) 219-7905 Email: m...@lunarg.com Website: http://www.lunarg.com -- SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel -- SOLARIS 10 is the OS for Data Centers - provides features such as DTrace, Predictive Self Healing and Award Winning ZFS. Get Solaris 10 NOW http://p.sf.net/sfu/solaris-dev2dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: vmwgfx + VMWare 7.0 - libdrm modetest.c
On Tue, Feb 9, 2010 at 8:05 AM, Peter Hanzel hanzelpe...@gmail.com wrote: Hello. I have a question about libdrm/libkms and test/modetest/modetest.c. I am now working with vmwgfx + VMWare 7.0, where vmwgfx had correctly initialized framebuffer and also now using fbcon. Now I want to test it woth modetest.c This program is only for intel so i recoded it to use libkms functions. Could you send the changes to make modetest.c use libkms as a patch? It's a good idea. cheers, Kristian -- The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: Removal of mach64
On Sun, Feb 7, 2010 at 1:32 AM, Catalin Patulea c...@vv.carleton.ca wrote: Hello, I am interested in getting DRI working on my ATI Rage XL card under 2.6.31-14 with mach64_drv 6.8.2 (Xorg 1.6.3 from Ubuntu Karmic koala). Git says that the mach64 driver was deleted, along with shared-code, linux-core, etc, in commit 9dd361. Do these drivers live anywhere else now? Has anyone tried compiling them against a recent kernel? They live in the kernel. cheers, Kristian -- The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] libdrm compile warnings fixes
On Thu, Feb 4, 2010 at 2:23 PM, Matthew W. S. Bell matt...@bells23.org.uk wrote: Hi, I've fixed up some compile warnings in the attached patch; I think a couple of cases may actually have been bugs. One case I have not touched is converting between void * (64 bit here) and drm_handle_t (32 bit here), as I don't understand the issues here; it would be nice if no warnings were emitted if it is safe. Thanks for the patch, I just applied it. Additionally, the function libdrm/xf86drmSL.c:drmSLLookupNeighbors() appears to be completely broken as it computes on the variable update which is unconditionally undefined. Yeah, nothing really uses the skip list and I'd like to drop it and the hash table. I guess it's not a big deal though... cheers, Kristian -- The Planet: dedicated and managed hosting, cloud storage, colocation Stay online with enterprise data centers and the best network in the business Choose flexible plans and management services without long-term contracts Personal 24x7 support from experience hosting pros just a phone call away. http://p.sf.net/sfu/theplanet-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: RFC: xfree: dri2: libdrm as optional
On Tue, Jan 19, 2010 at 2:18 PM, Tiago Vignatti tiago.vigna...@nokia.com wrote: Some drivers use DRI2 protocol but implement their own kernel rendering mananger. For these drivers, libdrm becomes useless. Yeah, I think this could be ok. The drm usage in DRI2 does stick out a bit, and should probably be pushed to the driver. I'm just really curious what memory manager you're using :) 2. hide all trickery inside xorg driver, adding a new field to DRI2InfoRec: Bool DRI2Authenticate(ScreenPtr pScreen, unsigned int magic) { DRI2ScreenPtr ds = DRI2GetScreen(pScreen); if (ds == NULL || (*ds-AuthMagic)(ds-fd, magic)) return FALSE; return TRUE; } It would have to be this alternative, except it break backwards compatibility, since if a drivers doesn't implement the new AuthMagic hook, the clients wont be authenticated. Maybe we could add a ./configure option to disable drm usage in DRI2, but default it to enabled. Then DRI2 should fail to initialize if it doesn't have either the current drm call or the hook and if it has both prefer the new hook. Alternative 2. seems more complete but requires code changes all over the drivers. I'm more inclined for this alternative... Moreover, for both alternatives we need to do something with drm_magic_t type - can we just use unsigned int instead declare such new type? We can use either CARD32 or uint32_t, but probably uint32_t. cheers, Kristian -- Throughout its 18-year history, RSA Conference consistently attracts the world's best and brightest in the field, creating opportunities for Conference attendees to learn about information security's most important issues through interactions with peers, luminaries and emerging and established companies. http://p.sf.net/sfu/rsaconf-dev2dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm/i915: Clean up vblank data after lastclose and unload
Otherwise we end up waking up a freed waitqueue. Signed-off-by: Kristian Høgsberg k...@bitplanet.net --- Resend. This didn't get picked up earlier, so this time I'll try sending to the right mailing list. drivers/gpu/drm/drm_stub.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index ad73e14..3735478 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -515,8 +515,6 @@ void drm_put_dev(struct drm_device *dev) } driver = dev-driver; - drm_vblank_cleanup(dev); - drm_lastclose(dev); if (drm_core_has_MTRR(dev) drm_core_has_AGP(dev) @@ -531,6 +529,8 @@ void drm_put_dev(struct drm_device *dev) if (dev-driver-unload) dev-driver-unload(dev); + drm_vblank_cleanup(dev); + if (drm_core_has_AGP(dev) dev-agp) { kfree(dev-agp); dev-agp = NULL; -- 1.6.5.rc2 -- This SF.Net email is sponsored by the Verizon Developer Community Take advantage of Verizon's best-in-class app development support A streamlined, 14 day to market process makes app distribution fast and easy Join now and get one step closer to millions of Verizon customers http://p.sf.net/sfu/verizon-dev2dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[ANNOUNCE] libdrm 2.4.16
Hello, Here's the 2.4.16 release of libdrm. There are a lot of changes this time, in particular we dropped the orphaned driver code from Linux and BSD and this release is now really just libdrm. Going forward, the drm header files we ship in libdrm will be a straight copy from the linux kernel header files. Once a feature is merged into the drm-next branch of Dave's kernel tree the header files can be copied from $kernel_src/usr/include/drm into libdrm and userspace support for the new functionality can be added. cheers, Kristian Alex Deucher (1): Add missing DRM_MAX_MINOR define Ben Skeggs (7): nouveau: function to return status of bo being referenced in pushbuf nouveau: retry if pushbuf ioctl interrupted by signal nouveau: update view of available aperture space after each flush nouveau: drop rendering on the floor rather than asserting if flush fails nouveau: add reloc refcnt to pending bo list nouveau: modify api slightly to allow caller to handle reloc failures nouveau: turn another assertion into an error Chris Wilson (14): configure: Conditionally build libdrm_intel configure: Typo in error message. intel: Fallback to atomic-ops.h [libatomic-ops-dev] intel: Export madvise intel: Only store a buffer in the cache if it is retained. intel: Apply pessimistic alignment to in-aperture buffer size intel: Clear bo-used_as_reloc_target flag on destroy intel: Wrap a few more syscalls with EINTR protection intel: Remove the extra reference while validating the reloc tree intel: Make bo_reference() inline for internal use. intel: Review use of errno. intel: Repeat execbuffer after EINTR intel: Check and propagate errors from building reloc-tree intel: Free memory before inserting bo into cache. Eric Anholt (3): intel: Add the defines for the kernel overlay support landing in 2.6.33. intel: Improve bo_references performance by skipping the tree walk. intel: Only call clock_gettime once per unreference_final. Francisco Jerez (1): nouveau: Update some nouveau_class.h definitions from renouveau.xml. Julien Cristau (1): Only install libdrm_intel.pc if we build libdrm_intel Kristian Høgsberg (18): Add support for vblank events Add makefile rule to copy headers from kernel tree Copy headers from kernel v2.6.32-rc6-130-g5b8f0be Fix typo in i915 pipe_from_crtc_id ioctl struct name Use headers copied from kernel instead of shared-core Drop shared-core, bsd-core, linux-core and scripts subdirs Move libdrm/ up one level Drop stale TODO and unused ChangeLog Update README Install kernel headers in ${includedir}/drm Put mach64_drm.h back in to avoid breaking mesa build Drop duplicated radeon_*.h files in include/drm Output summary of enabled features at the end of configure.ac Don't hardcore 'yes', use in configure.ac output Fix build on *BSD Add drmGetDeviceNameFromFd function Enable experimental APIs for distcheck Bump to 2.4.16 for release Maciej Cencora (1): libdrm_radeon: add radeon_bo_is_referenced_by_cs function Mathias Fröhlich (1): radeon: fix allocation Patrice Mandin (1): nouveau: nv30: add render target logbase2 width,height Pekka Paalanen (1): nouveau: fix DRM headers Robert Noland (3): Finish fixing the build on FreeBSD More fixups to allow mesa to build Correctly set DRM_MAX_MINOR for all platforms. git tag: 2.4.16 http://dri.freedesktop.org/libdrm/libdrm-2.4.16.tar.bz2 MD5: fa47a49641a8e846510566787a85cb8b libdrm-2.4.16.tar.bz2 SHA1: 9f3580046429e88d4cd7f0e72e715f887fa42047 libdrm-2.4.16.tar.bz2 http://dri.freedesktop.org/libdrm/libdrm-2.4.16.tar.gz MD5: 40d07cde67997e3329146836754ff432 libdrm-2.4.16.tar.gz SHA1: dea5b1c683cb1498729a7af08356c8066a3c5c9b libdrm-2.4.16.tar.gz -- Join us December 9, 2009 for the Red Hat Virtual Experience, a free event focused on virtualization and cloud computing. Attend in-depth sessions from your desk. Your couch. Anywhere. http://p.sf.net/sfu/redhat-sfdev2dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm: Add compatibility #ifdefs for *BSD
This let's use use the linux drm headers as the canonical source for libdrm on all platforms. Signed-off-by: Kristian Høgsberg k...@bitplanet.net --- This is the patch to sync the linux kernel headers with what's in libdrm now. With this patch upstream, we can copy headers from the kernel into the libdrm repo unchanged. include/drm/drm.h| 29 +++-- include/drm/drm_mode.h |3 --- include/drm/i915_drm.h |4 ++-- include/drm/mga_drm.h|2 +- include/drm/radeon_drm.h |2 +- include/drm/via_drm.h|2 +- 6 files changed, 24 insertions(+), 18 deletions(-) diff --git a/include/drm/drm.h b/include/drm/drm.h index 7cb50bd..838bce9 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -36,17 +36,27 @@ #ifndef _DRM_H_ #define _DRM_H_ +#if defined(__linux__) + #include linux/types.h -#include asm/ioctl.h /* For _IO* macros */ -#define DRM_IOCTL_NR(n)_IOC_NR(n) -#define DRM_IOC_VOID _IOC_NONE -#define DRM_IOC_READ _IOC_READ -#define DRM_IOC_WRITE _IOC_WRITE -#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE -#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#include asm/ioctl.h +typedef unsigned int drm_handle_t; + +#else /* One of the BSDs */ -#define DRM_MAJOR 226 -#define DRM_MAX_MINOR 15 +#include sys/ioccom.h +#include sys/types.h +typedef int8_t __s8; +typedef uint8_t __u8; +typedef int16_t __s16; +typedef uint16_t __u16; +typedef int32_t __s32; +typedef uint32_t __u32; +typedef int64_t __s64; +typedef uint64_t __u64; +typedef unsigned long drm_handle_t; + +#endif #define DRM_NAME drm /** Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /** At least 2^5 bytes = 32 bytes */ @@ -59,7 +69,6 @@ #define _DRM_LOCK_IS_CONT(lock) ((lock) _DRM_LOCK_CONT) #define _DRM_LOCKING_CONTEXT(lock) ((lock) ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) -typedef unsigned int drm_handle_t; typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 1f90841..852505e 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -27,9 +27,6 @@ #ifndef _DRM_MODE_H #define _DRM_MODE_H -#include linux/kernel.h -#include linux/types.h - #define DRM_DISPLAY_INFO_LEN 32 #define DRM_CONNECTOR_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 7e0cb1d..a04c3ab 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -27,11 +27,11 @@ #ifndef _I915_DRM_H_ #define _I915_DRM_H_ +#include drm.h + /* Please note that modifications to all structs defined here are * subject to backwards-compatibility constraints. */ -#include linux/types.h -#include drm.h /* Each region is a minimum of 16k, and there are at most 255 of them. */ diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h index 325fd6f..3ffbc47 100644 --- a/include/drm/mga_drm.h +++ b/include/drm/mga_drm.h @@ -35,7 +35,7 @@ #ifndef __MGA_DRM_H__ #define __MGA_DRM_H__ -#include linux/types.h +#include drm.h /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (mga_sarea.h) diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 3b9932a..39537f3 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -33,7 +33,7 @@ #ifndef __RADEON_DRM_H__ #define __RADEON_DRM_H__ -#include linux/types.h +#include drm.h /* WARNING: If you change any of these defines, make sure to change the * defines in the X server file (radeon_sarea.h) diff --git a/include/drm/via_drm.h b/include/drm/via_drm.h index 170786e..fd11a5b 100644 --- a/include/drm/via_drm.h +++ b/include/drm/via_drm.h @@ -24,7 +24,7 @@ #ifndef _VIA_DRM_H_ #define _VIA_DRM_H_ -#include linux/types.h +#include drm.h /* WARNING: These defines must be the same as what the Xserver uses. * if you change them, you must change the defines in the Xserver. -- 1.6.5.rc2 -- Join us December 9, 2009 for the Red Hat Virtual Experience, a free event focused on virtualization and cloud computing. Attend in-depth sessions from your desk. Your couch. Anywhere. http://p.sf.net/sfu/redhat-sfdev2dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] drm: Add compatibility #ifdefs for *BSD
2009/12/2 Robert Noland rnol...@2hip.net: On Wed, 2009-12-02 at 11:36 -0500, Kristian Høgsberg wrote: This let's use use the linux drm headers as the canonical source for libdrm on all platforms. Signed-off-by: Kristian Høgsberg k...@bitplanet.net --- This is the patch to sync the linux kernel headers with what's in libdrm now. With this patch upstream, we can copy headers from the kernel into the libdrm repo unchanged. ... This does not look like the latest version with the DRM_MAX_MINOR shuffle. Are you planning to handle that with a separate patch? DRM_MAX_MINOR is only used in userspace, but this patch does break linux kernel compile. I need to move a couple of #defines deteled from drm.h to drmP.h. New patch on the way. thanks, Kristian -- Join us December 9, 2009 for the Red Hat Virtual Experience, a free event focused on virtualization and cloud computing. Attend in-depth sessions from your desk. Your couch. Anywhere. http://p.sf.net/sfu/redhat-sfdev2dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm: Add compatibility #ifdefs for *BSD
This let's use use the linux drm headers as the canonical source for libdrm on all platforms. Signed-off-by: Kristian Høgsberg k...@bitplanet.net --- Second try, now with the #defines added to drmP.h that was missing in the first patch. include/drm/drm.h| 29 +++-- include/drm/drmP.h |3 +++ include/drm/drm_mode.h |3 --- include/drm/i915_drm.h |4 ++-- include/drm/mga_drm.h|2 +- include/drm/radeon_drm.h |2 +- include/drm/via_drm.h|2 +- 7 files changed, 27 insertions(+), 18 deletions(-) diff --git a/include/drm/drm.h b/include/drm/drm.h index 7cb50bd..838bce9 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -36,17 +36,27 @@ #ifndef _DRM_H_ #define _DRM_H_ +#if defined(__linux__) + #include linux/types.h -#include asm/ioctl.h /* For _IO* macros */ -#define DRM_IOCTL_NR(n)_IOC_NR(n) -#define DRM_IOC_VOID _IOC_NONE -#define DRM_IOC_READ _IOC_READ -#define DRM_IOC_WRITE _IOC_WRITE -#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE -#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#include asm/ioctl.h +typedef unsigned int drm_handle_t; + +#else /* One of the BSDs */ -#define DRM_MAJOR 226 -#define DRM_MAX_MINOR 15 +#include sys/ioccom.h +#include sys/types.h +typedef int8_t __s8; +typedef uint8_t __u8; +typedef int16_t __s16; +typedef uint16_t __u16; +typedef int32_t __s32; +typedef uint32_t __u32; +typedef int64_t __s64; +typedef uint64_t __u64; +typedef unsigned long drm_handle_t; + +#endif #define DRM_NAME drm /** Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /** At least 2^5 bytes = 32 bytes */ @@ -59,7 +69,6 @@ #define _DRM_LOCK_IS_CONT(lock) ((lock) _DRM_LOCK_CONT) #define _DRM_LOCKING_CONTEXT(lock) ((lock) ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) -typedef unsigned int drm_handle_t; typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c8e64bb..5a9582b 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -322,6 +322,9 @@ typedef int drm_ioctl_t(struct drm_device *dev, void *data, typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, unsigned long arg); +#define DRM_IOCTL_NR(n)_IOC_NR(n) +#define DRM_MAJOR 226 + #define DRM_AUTH 0x1 #defineDRM_MASTER 0x2 #define DRM_ROOT_ONLY 0x4 diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 1f90841..852505e 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -27,9 +27,6 @@ #ifndef _DRM_MODE_H #define _DRM_MODE_H -#include linux/kernel.h -#include linux/types.h - #define DRM_DISPLAY_INFO_LEN 32 #define DRM_CONNECTOR_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 7e0cb1d..a04c3ab 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -27,11 +27,11 @@ #ifndef _I915_DRM_H_ #define _I915_DRM_H_ +#include drm.h + /* Please note that modifications to all structs defined here are * subject to backwards-compatibility constraints. */ -#include linux/types.h -#include drm.h /* Each region is a minimum of 16k, and there are at most 255 of them. */ diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h index 325fd6f..3ffbc47 100644 --- a/include/drm/mga_drm.h +++ b/include/drm/mga_drm.h @@ -35,7 +35,7 @@ #ifndef __MGA_DRM_H__ #define __MGA_DRM_H__ -#include linux/types.h +#include drm.h /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (mga_sarea.h) diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 3b9932a..39537f3 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -33,7 +33,7 @@ #ifndef __RADEON_DRM_H__ #define __RADEON_DRM_H__ -#include linux/types.h +#include drm.h /* WARNING: If you change any of these defines, make sure to change the * defines in the X server file (radeon_sarea.h) diff --git a/include/drm/via_drm.h b/include/drm/via_drm.h index 170786e..fd11a5b 100644 --- a/include/drm/via_drm.h +++ b/include/drm/via_drm.h @@ -24,7 +24,7 @@ #ifndef _VIA_DRM_H_ #define _VIA_DRM_H_ -#include linux/types.h +#include drm.h /* WARNING: These defines must be the same as what the Xserver uses. * if you change them, you must change the defines in the Xserver. -- 1.6.5.rc2 -- Join us December 9, 2009 for the Red Hat Virtual Experience, a free event focused on virtualization and cloud computing. Attend in-depth sessions from your desk. Your couch. Anywhere. http://p.sf.net/sfu/redhat-sfdev2dev -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https
Re: [PATCH 2/2] drm: use page flip event to signal flip completion
2009/11/19 Jesse Barnes jbar...@virtuousgeek.org: From fa621056b43d24ca97b61863c8566ac12696ce25 Mon Sep 17 00:00:00 2001 From: Jesse Barnes jbar...@virtuousgeek.org Date: Thu, 19 Nov 2009 10:25:46 -0800 Subject: [PATCH 2/2] drm: use page flip event to signal flip completion We don't actually know which frame number the flip will complete on, so userspace needs a specific flip notification to tell it when the last flip completed. Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org Acked-by: Kristian Høgsberg k...@bitplanet.net --- drivers/gpu/drm/drm_crtc.c | 2 +- include/drm/drm.h | 1 + 2 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index ac2fa19..3bc870d 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2527,7 +2527,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, goto out; } - e-event.base.type = DRM_EVENT_VBLANK; + e-event.base.type = DRM_EVENT_FLIP_COMPLETE; e-event.base.length = sizeof e-event; e-event.user_data = page_flip-user_data; e-base.event = e-event.base; diff --git a/include/drm/drm.h b/include/drm/drm.h index 3919a4f..309d0a5 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -718,6 +718,7 @@ struct drm_event { }; #define DRM_EVENT_VBLANK 0x01 +#define DRM_EVENT_FLIP_COMPLETE 0x02 struct drm_event_vblank { struct drm_event base; -- 1.6.1.3 -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] drm/i915: Add intel implementation of the pageflip ioctl
2009/11/19 Jesse Barnes jbar...@virtuousgeek.org: Dave, here's an updated version that fixes the checkpatch warnings, removes a stray line (the forced alignment hack) and fixes pre-965 support. I have some related followup patches, but I think this one is ready. Thanks, Jesse -- From 2bec6039e7e6180a981971665be712f5a5b9b0e0 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= k...@bitplanet.net Date: Tue, 17 Nov 2009 12:43:56 -0500 Subject: [PATCH 1/4] Add intel implementation of the pageflip ioctl MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Acked-by: Jakob Bornecrantz ja...@vmware.com Acked-by: Thomas Hellström tho...@shipmail.org Review-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Jesse Orange Smoothie Barnes jbar...@virtuousgeek.org Signed-off-by: Kristian Høgsberg k...@bitplanet.net Hmm, I'm already the author of this patch, can I ack it? *confused* Anyway, with Jesse's fixes, the ioctl is actually useful, so: Acked-by: Kristian Høgsberg k...@bitplanet.net drivers/gpu/drm/i915/i915_drv.h | 12 ++ drivers/gpu/drm/i915/i915_gem.c | 64 +- drivers/gpu/drm/i915/i915_irq.c | 10 ++ drivers/gpu/drm/i915/i915_reg.h | 2 + drivers/gpu/drm/i915/intel_display.c | 237 +- drivers/gpu/drm/i915/intel_drv.h | 3 + 6 files changed, 294 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 835625b..75acb5d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -536,6 +536,10 @@ typedef struct drm_i915_private { /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; + struct drm_crtc *plane_to_crtc_mapping[2]; + struct drm_crtc *pipe_to_crtc_mapping[2]; + wait_queue_head_t pending_flip_queue; + /* Reclocking support */ bool render_reclock_avail; bool lvds_downclock_avail; @@ -635,6 +639,13 @@ struct drm_i915_gem_object { * Advice: are the backing pages purgeable? */ int madv; + + /** + * Number of crtcs where this object is currently the fb, but + * will be page flipped away on the next vblank. When it + * reaches 0, dev_priv-pending_flip_queue will be woken up. + */ + atomic_t pending_flip; }; /** @@ -826,6 +837,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev); int i915_gem_object_get_pages(struct drm_gem_object *obj); void i915_gem_object_put_pages(struct drm_gem_object *obj); void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); +void i915_gem_object_flush_write_domain(struct drm_gem_object *obj); void i915_gem_shrinker_init(void); void i915_gem_shrinker_exit(void); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2065b8f..55ed06f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2771,6 +2771,22 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) old_write_domain); } +void +i915_gem_object_flush_write_domain(struct drm_gem_object *obj) +{ + switch (obj-write_domain) { + case I915_GEM_DOMAIN_GTT: + i915_gem_object_flush_gtt_write_domain(obj); + break; + case I915_GEM_DOMAIN_CPU: + i915_gem_object_flush_cpu_write_domain(obj); + break; + default: + i915_gem_object_flush_gpu_write_domain(obj); + break; + } +} + /** * Moves a single object to the GTT read, and possibly write domain. * @@ -3536,6 +3552,41 @@ i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec, return 0; } +static int +i915_gem_wait_for_pending_flip(struct drm_device *dev, + struct drm_gem_object **object_list, + int count) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + struct drm_i915_gem_object *obj_priv; + DEFINE_WAIT(wait); + int i, ret = 0; + + for (;;) { + prepare_to_wait(dev_priv-pending_flip_queue, + wait, TASK_INTERRUPTIBLE); + for (i = 0; i count; i++) { + obj_priv = object_list[i]-driver_private; + if (atomic_read(obj_priv-pending_flip) 0) + break; + } + if (i == count) + break; + + if (!signal_pending(current)) { + mutex_unlock(dev-struct_mutex); + schedule(); + mutex_lock(dev-struct_mutex); + continue
Re: RFC: libdrm repo
On Sat, Nov 28, 2009 at 1:41 PM, Robert Noland rnol...@2hip.net wrote: On Fri, 2009-11-27 at 17:23 -0800, vehemens wrote: ... I think we pissed one person off, not people, as I said, there are two people registered as BSD maintainers for drm code, oga and rnoland, neither of them cared. I'm not sure what value the codebase has if neither Free or OpenBSD are going to use it. You pissed a number of people off, but the difference with me is that I'm not letting either of you get away with it. There are more then two BSD maintainers, and your statement that neither of them cared is not correct. Don't get me wrong here, I don't like the current state of things, but given current drm development practices, this change was irrelevant. I was a bit frustrated at the build breakage for libdrm, but krh and I worked through that and it is now resolved. That was my understanding of things as well. I wouldn't have dropped the linux-core or bsd-core subdirectories if there was still work going on there. Again, apologies for the build breakage and thanks for having the patience to help work it out. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm: Add minimal BSD #ifdefs so we can share the drm.h unchanged
We ship a copy of drm.h in the libdrm repo. By adding these couple of ifdefs, we can share the drm.h header file between kernel source and libdrm on linux and the BSDs. Signed-off-by: Kristian Høgsberg k...@bitplanet.net --- include/drm/drm.h| 29 +++-- include/drm/drmP.h | 10 ++ include/drm/drm_mode.h |3 --- include/drm/i915_drm.h |4 ++-- include/drm/mga_drm.h|2 +- include/drm/radeon_drm.h |2 +- include/drm/via_drm.h|2 +- 7 files changed, 34 insertions(+), 18 deletions(-) diff --git a/include/drm/drm.h b/include/drm/drm.h index 3919a4f..0114ac9 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -36,17 +36,27 @@ #ifndef _DRM_H_ #define _DRM_H_ +#if defined(__linux__) + #include linux/types.h -#include asm/ioctl.h /* For _IO* macros */ -#define DRM_IOCTL_NR(n)_IOC_NR(n) -#define DRM_IOC_VOID _IOC_NONE -#define DRM_IOC_READ _IOC_READ -#define DRM_IOC_WRITE _IOC_WRITE -#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE -#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) +#include asm/ioctl.h +typedef unsigned int drm_handle_t; + +#else /* One of the BSDs */ -#define DRM_MAJOR 226 -#define DRM_MAX_MINOR 15 +#include sys/ioccom.h +#include sys/types.h +typedef int8_t __s8; +typedef uint8_t __u8; +typedef int16_t __s16; +typedef uint16_t __u16; +typedef int32_t __s32; +typedef uint32_t __u32; +typedef int64_t __s64; +typedef uint64_t __u64; +typedef unsigned long drm_handle_t; + +#endif #define DRM_NAME drm /** Name in kernel, /dev, and /proc */ #define DRM_MIN_ORDER 5 /** At least 2^5 bytes = 32 bytes */ @@ -59,7 +69,6 @@ #define _DRM_LOCK_IS_CONT(lock) ((lock) _DRM_LOCK_CONT) #define _DRM_LOCKING_CONTEXT(lock) ((lock) ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT)) -typedef unsigned int drm_handle_t; typedef unsigned int drm_context_t; typedef unsigned int drm_drawable_t; typedef unsigned int drm_magic_t; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 1b72a52..65a3369 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -289,6 +289,16 @@ typedef int drm_ioctl_t(struct drm_device *dev, void *data, typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, unsigned long arg); +#define DRM_MAJOR 226 +#define DRM_MAX_MINOR 15 + +#define DRM_IOCTL_NR(n)_IOC_NR(n) +#define DRM_IOC_VOID _IOC_NONE +#define DRM_IOC_READ _IOC_READ +#define DRM_IOC_WRITE _IOC_WRITE +#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE +#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size) + #define DRM_AUTH 0x1 #defineDRM_MASTER 0x2 #define DRM_ROOT_ONLY 0x4 diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 68ddc61..09ca6ad 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -27,9 +27,6 @@ #ifndef _DRM_MODE_H #define _DRM_MODE_H -#include linux/kernel.h -#include linux/types.h - #define DRM_DISPLAY_INFO_LEN 32 #define DRM_CONNECTOR_NAME_LEN 32 #define DRM_DISPLAY_MODE_LEN 32 diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 7e0cb1d..a04c3ab 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -27,11 +27,11 @@ #ifndef _I915_DRM_H_ #define _I915_DRM_H_ +#include drm.h + /* Please note that modifications to all structs defined here are * subject to backwards-compatibility constraints. */ -#include linux/types.h -#include drm.h /* Each region is a minimum of 16k, and there are at most 255 of them. */ diff --git a/include/drm/mga_drm.h b/include/drm/mga_drm.h index 325fd6f..3ffbc47 100644 --- a/include/drm/mga_drm.h +++ b/include/drm/mga_drm.h @@ -35,7 +35,7 @@ #ifndef __MGA_DRM_H__ #define __MGA_DRM_H__ -#include linux/types.h +#include drm.h /* WARNING: If you change any of these defines, make sure to change the * defines in the Xserver file (mga_sarea.h) diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 3b9932a..39537f3 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h @@ -33,7 +33,7 @@ #ifndef __RADEON_DRM_H__ #define __RADEON_DRM_H__ -#include linux/types.h +#include drm.h /* WARNING: If you change any of these defines, make sure to change the * defines in the X server file (radeon_sarea.h) diff --git a/include/drm/via_drm.h b/include/drm/via_drm.h index 170786e..fd11a5b 100644 --- a/include/drm/via_drm.h +++ b/include/drm/via_drm.h @@ -24,7 +24,7 @@ #ifndef _VIA_DRM_H_ #define _VIA_DRM_H_ -#include linux/types.h +#include drm.h /* WARNING: These defines must be the same as what the Xserver uses. * if you change them, you must change the defines in the Xserver. -- 1.6.5.rc2 -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30
Re: RFC: libdrm repo
2009/11/23 Michel Dänzer mic...@daenzer.net: On Fri, 2009-11-20 at 17:20 -0500, Kristian Høgsberg wrote: 2009/11/19 Eric Anholt e...@anholt.net: On Tue, 2009-11-17 at 11:33 -0500, Kristian Høgsberg wrote: 2009/11/6 Kristian Høgsberg k...@bitplanet.net: Hi, This has come up a few time and it's something I think makes a lot of sense. Since all driver development (afaik) now happens in linux kernel tree, it makes sense to drop the driver bits from the drm.git repo. Ok, here's an update to the proposal. I've rebased the libdrm branch in people.freedesktop.org/~krh/libdrm.git to include a copy of $kernel_source/usr/include/drm as a toplevel include/drm directory in git. I also added a makefile rule to copy a new version of the headers from a kernel git repo and commit it with a message describing the version it was copied from. The location of the kernel repo is given at ./configure time with the --with-kernel-source argument. By adding the makefile rule, I'd like to encourage people to not hand edit the headers and to commit updates of the header files independently from other changes. And of course, updates to the headers should still follow the rules we have now; only copy over new changes once they're in drm-next (I think, or is that in Linus' tree?). Anyway, I think this should address the concerns raised in the thread and if there's no other problems, I can put this into place today. I'll merge the couple of changes on master since I branched for this work and I'll put a mesa/drm.git symlink in place to point to libdrm.git. Awesome. Just a touchup to the README to reflect the current state seems to be needed. Done and pushed. Is it expected that there are now two slightly different sets of radeon headers in the repo? Which set will get installed? The headers in include/drm will be installed and libdrm_radeon should be updated to use those headers instead of the ones in radeon/ since they're what's upstream. I'm probably not the best person to make those change, but I can try to fix that up if nobody else are up for it. thanks, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: RFC: libdrm repo
2009/11/23 Michel Dänzer mic...@daenzer.net: On Mon, 2009-11-23 at 10:55 -0500, Kristian Høgsberg wrote: 2009/11/23 Michel Dänzer mic...@daenzer.net: On Fri, 2009-11-20 at 17:20 -0500, Kristian Høgsberg wrote: 2009/11/19 Eric Anholt e...@anholt.net: On Tue, 2009-11-17 at 11:33 -0500, Kristian Høgsberg wrote: 2009/11/6 Kristian Høgsberg k...@bitplanet.net: Hi, This has come up a few time and it's something I think makes a lot of sense. Since all driver development (afaik) now happens in linux kernel tree, it makes sense to drop the driver bits from the drm.git repo. Ok, here's an update to the proposal. I've rebased the libdrm branch in people.freedesktop.org/~krh/libdrm.git to include a copy of $kernel_source/usr/include/drm as a toplevel include/drm directory in git. I also added a makefile rule to copy a new version of the headers from a kernel git repo and commit it with a message describing the version it was copied from. The location of the kernel repo is given at ./configure time with the --with-kernel-source argument. By adding the makefile rule, I'd like to encourage people to not hand edit the headers and to commit updates of the header files independently from other changes. And of course, updates to the headers should still follow the rules we have now; only copy over new changes once they're in drm-next (I think, or is that in Linus' tree?). Anyway, I think this should address the concerns raised in the thread and if there's no other problems, I can put this into place today. I'll merge the couple of changes on master since I branched for this work and I'll put a mesa/drm.git symlink in place to point to libdrm.git. Awesome. Just a touchup to the README to reflect the current state seems to be needed. Done and pushed. Is it expected that there are now two slightly different sets of radeon headers in the repo? Which set will get installed? The headers in include/drm will be installed and libdrm_radeon should be updated to use those headers instead of the ones in radeon/ since they're what's upstream. At least one of the headers in question - radeon_bo.h - isn't in the kernel (and it probably makes no sense to put userland specific headers like that in the kernel) and is outdated in include/drm. Oh, only radeon_drm.h is in the kernel, so only that should be in include/drm. The other radeon_*.h files live in radeon/. I guess accidentally copied over the userspace headers when I populated the include/drm directory initially. Should be cleaned up now. thanks, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: libdrm headers (Re: RFC: libdrm repo)
On Mon, Nov 23, 2009 at 11:50 AM, Pekka Paalanen p...@iki.fi wrote: On Mon, 23 Nov 2009 17:12:07 +0100 Michel Dänzer mic...@daenzer.net wrote: On Mon, 2009-11-23 at 10:55 -0500, Kristian Høgsberg wrote: The headers in include/drm will be installed and libdrm_radeon should be updated to use those headers instead of the ones in radeon/ since they're what's upstream. At least one of the headers in question - radeon_bo.h - isn't in the kernel (and it probably makes no sense to put userland specific headers like that in the kernel) and is outdated in include/drm. Now that we are talking about headers, what is the proper layout of *installed* headers? I'm leaving out $prefix in the following. include/drm/ I'd assume that should contain only the kernel headers, and those are going a away soonish or ASAP. (krh already tried to remove them ;-) include/drm/ seems to be also containing libdrm_radeon user API headers? include/intel_bufmgr.h libdrm_intel has their header sitting in the root include dir. include/nouveau/ almost all libdrm_nouveau headers are here, except nouveau_drmif.h, which should probably be moved. include/xf86drm.h include/xf86drmMode.h and then these two... So, each of the three drivers have their headers installed differently, and Nouveau manages to fail even in that. :-) What should installed header tree look like? Yup, as far as I can tell that's what it looked like before my re-org and it's what it finally looks like again. I defnitely agree that it's not an ideal layout, but we can't change it without breaking things. However, now that we use .pc files we should be able to move things around without recent libdrm users breaking. I'm not sure if it's worthwhile though, but if we're moving files around, it's something we can do (mostly) on a per driver basis, but we should of course agree on what kind of layout we want. I'd suggest keeping only kernel header files in include/drm, moving xf86drm.h and xf86drmMode.h to /usr/include/libdrm and moving chipset headers to /usr/include/libdrm/$chipset. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: RFC: libdrm repo
2009/11/19 Eric Anholt e...@anholt.net: On Tue, 2009-11-17 at 11:33 -0500, Kristian Høgsberg wrote: 2009/11/6 Kristian Høgsberg k...@bitplanet.net: Hi, This has come up a few time and it's something I think makes a lot of sense. Since all driver development (afaik) now happens in linux kernel tree, it makes sense to drop the driver bits from the drm.git repo. Ok, here's an update to the proposal. I've rebased the libdrm branch in people.freedesktop.org/~krh/libdrm.git to include a copy of $kernel_source/usr/include/drm as a toplevel include/drm directory in git. I also added a makefile rule to copy a new version of the headers from a kernel git repo and commit it with a message describing the version it was copied from. The location of the kernel repo is given at ./configure time with the --with-kernel-source argument. By adding the makefile rule, I'd like to encourage people to not hand edit the headers and to commit updates of the header files independently from other changes. And of course, updates to the headers should still follow the rules we have now; only copy over new changes once they're in drm-next (I think, or is that in Linus' tree?). Anyway, I think this should address the concerns raised in the thread and if there's no other problems, I can put this into place today. I'll merge the couple of changes on master since I branched for this work and I'll put a mesa/drm.git symlink in place to point to libdrm.git. Awesome. Just a touchup to the README to reflect the current state seems to be needed. Done and pushed. I left the repo as mesa/drm, but I think it makes sense to move it to be a toplevel repo and rename it libdrm. I don't have the admin-fu to that myself so I'll need somebody with those skills to do that for me. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH 2/2 v2] drm/i915: Add intel implementation of the pageflip ioctl
Acked-by: Jakob Bornecrantz ja...@vmware.com Acked-by: Thomas Hellström tho...@shipmail.org Review-by: Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Jesse Orange Smoothie Barnes jbar...@virtuousgeek.org Signed-off-by: Kristian Høgsberg k...@bitplanet.net --- Resend to add missing acks and sob's and to fix checkpatch errors. cheers, Kristian drivers/gpu/drm/i915/i915_drv.h | 12 ++ drivers/gpu/drm/i915/i915_gem.c | 64 +- drivers/gpu/drm/i915/i915_irq.c | 19 +++- drivers/gpu/drm/i915/i915_reg.h |2 + drivers/gpu/drm/i915/intel_display.c | 228 +- drivers/gpu/drm/i915/intel_drv.h |4 + 6 files changed, 291 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 57204e2..224a0ab 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -527,6 +527,10 @@ typedef struct drm_i915_private { /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; + struct drm_crtc *plane_to_crtc_mapping[2]; + struct drm_crtc *pipe_to_crtc_mapping[2]; + wait_queue_head_t pending_flip_queue; + /* Reclocking support */ bool render_reclock_avail; bool lvds_downclock_avail; @@ -626,6 +630,13 @@ struct drm_i915_gem_object { * Advice: are the backing pages purgeable? */ int madv; + + /** +* Number of crtcs where this object is currently the fb, but +* will be page flipped away on the next vblank. When it +* reaches 0, dev_priv-pending_flip_queue will be woken up. +*/ + atomic_t pending_flip; }; /** @@ -812,6 +823,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev); int i915_gem_object_get_pages(struct drm_gem_object *obj); void i915_gem_object_put_pages(struct drm_gem_object *obj); void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); +void i915_gem_object_flush_write_domain(struct drm_gem_object *obj); void i915_gem_shrinker_init(void); void i915_gem_shrinker_exit(void); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index abfc27b..86511d1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2760,6 +2760,22 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) old_write_domain); } +void +i915_gem_object_flush_write_domain(struct drm_gem_object *obj) +{ + switch (obj-write_domain) { + case I915_GEM_DOMAIN_GTT: + i915_gem_object_flush_gtt_write_domain(obj); + break; + case I915_GEM_DOMAIN_CPU: + i915_gem_object_flush_cpu_write_domain(obj); + break; + default: + i915_gem_object_flush_gpu_write_domain(obj); + break; + } +} + /** * Moves a single object to the GTT read, and possibly write domain. * @@ -3525,6 +3541,41 @@ i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec, return 0; } +static int +i915_gem_wait_for_pending_flip(struct drm_device *dev, + struct drm_gem_object **object_list, + int count) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + struct drm_i915_gem_object *obj_priv; + DEFINE_WAIT(wait); + int i, ret = 0; + + for (;;) { + prepare_to_wait(dev_priv-pending_flip_queue, + wait, TASK_INTERRUPTIBLE); + for (i = 0; i count; i++) { + obj_priv = object_list[i]-driver_private; + if (atomic_read(obj_priv-pending_flip) 0) + break; + } + if (i == count) + break; + + if (!signal_pending(current)) { + mutex_unlock(dev-struct_mutex); + schedule(); + mutex_lock(dev-struct_mutex); + continue; + } + ret = -ERESTARTSYS; + break; + } + finish_wait(dev_priv-pending_flip_queue, wait); + + return ret; +} + int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -3540,7 +3591,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, int ret, ret2, i, pinned = 0; uint64_t exec_offset; uint32_t seqno, flush_domains, reloc_index; - int pin_tries; + int pin_tries, flips; #if WATCH_EXEC DRM_INFO(buffers_ptr %d buffer_count %d len %08x\n, @@ -3612,6 +3663,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, } /* Look up object handles */ + flips = 0; for (i = 0; i args-buffer_count; i++) { object_list[i
Re: RFC: libdrm repo
2009/11/6 Kristian Høgsberg k...@bitplanet.net: Hi, This has come up a few time and it's something I think makes a lot of sense. Since all driver development (afaik) now happens in linux kernel tree, it makes sense to drop the driver bits from the drm.git repo. Ok, here's an update to the proposal. I've rebased the libdrm branch in people.freedesktop.org/~krh/libdrm.git to include a copy of $kernel_source/usr/include/drm as a toplevel include/drm directory in git. I also added a makefile rule to copy a new version of the headers from a kernel git repo and commit it with a message describing the version it was copied from. The location of the kernel repo is given at ./configure time with the --with-kernel-source argument. By adding the makefile rule, I'd like to encourage people to not hand edit the headers and to commit updates of the header files independently from other changes. And of course, updates to the headers should still follow the rules we have now; only copy over new changes once they're in drm-next (I think, or is that in Linus' tree?). Anyway, I think this should address the concerns raised in the thread and if there's no other problems, I can put this into place today. I'll merge the couple of changes on master since I branched for this work and I'll put a mesa/drm.git symlink in place to point to libdrm.git. thanks, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: RFC: libdrm repo
2009/11/17 Stephane Marchesin marche...@icps.u-strasbg.fr: 2009/11/17 Kristian Høgsberg k...@bitplanet.net: 2009/11/6 Kristian Høgsberg k...@bitplanet.net: Hi, This has come up a few time and it's something I think makes a lot of sense. Since all driver development (afaik) now happens in linux kernel tree, it makes sense to drop the driver bits from the drm.git repo. Ok, here's an update to the proposal. I've rebased the libdrm branch in people.freedesktop.org/~krh/libdrm.git to include a copy of $kernel_source/usr/include/drm as a toplevel include/drm directory in git. I also added a makefile rule to copy a new version of the headers from a kernel git repo and commit it with a message describing the version it was copied from. The location of the kernel repo is given at ./configure time with the --with-kernel-source argument. By adding the makefile rule, I'd like to encourage people to not hand edit the headers and to commit updates of the header files independently from other changes. And of course, updates to the headers should still follow the rules we have now; only copy over new changes once they're in drm-next (I think, or is that in Linus' tree?). Anyway, I think this should address the concerns raised in the thread and if there's no other problems, I can put this into place today. For the record, I don't think my concerns were adressed. You're right, of course. However, my libdrm proposal wasn't an attempt to change how we work, it was merely a re-organisation of the drm.git repo to better reflect and support the de facto workflow. Whether we want libdrm in the kernel tree or not is a different discussion from this, as I see it. It may or may not be a good idea, but I'd rather not block this clean up on that discussion ;-) cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH 1/2] drm/i915: Add page flipping ioctl
This adds a page flipping ioctl to the KMS API. The ioctl takes an fb ID and a ctrc ID and flips the crtc to the given fb at the next vblank. The ioctl returns immediately but the flip doesn't happen until after any rendering that's currently queued up against the new framebuffer is done. After submitting a page flip, any execbuffer involving the old front buffer will block until the flip is completed. Optionally, a vblank event can be generated when the swap eventually happens. Signed-off-by: Kristian Høgsberg k...@bitplanet.net Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- drivers/gpu/drm/drm_crtc.c | 69 drivers/gpu/drm/drm_drv.c |1 + include/drm/drm.h |1 + include/drm/drm_crtc.h | 16 ++ include/drm/drm_mode.h | 33 + 5 files changed, 120 insertions(+), 0 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index ee0cde1..ac2fa19 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2479,3 +2479,72 @@ out: mutex_unlock(dev-mode_config.mutex); return ret; } + +int drm_mode_page_flip_ioctl(struct drm_device *dev, +void *data, struct drm_file *file_priv) +{ + struct drm_mode_crtc_page_flip *page_flip = data; + struct drm_mode_object *obj; + struct drm_crtc *crtc; + struct drm_framebuffer *fb; + struct drm_pending_vblank_event *e = NULL; + unsigned long flags; + int ret = -EINVAL; + + if (page_flip-flags ~DRM_MODE_PAGE_FLIP_FLAGS || + page_flip-reserved != 0) + return -EINVAL; + + mutex_lock(dev-mode_config.mutex); + obj = drm_mode_object_find(dev, page_flip-crtc_id, DRM_MODE_OBJECT_CRTC); + if (!obj) + goto out; + crtc = obj_to_crtc(obj); + + if (crtc-funcs-page_flip == NULL) + goto out; + + obj = drm_mode_object_find(dev, page_flip-fb_id, DRM_MODE_OBJECT_FB); + if (!obj) + goto out; + fb = obj_to_fb(obj); + + if (page_flip-flags DRM_MODE_PAGE_FLIP_EVENT) { + ret = -ENOMEM; + spin_lock_irqsave(dev-event_lock, flags); + if (file_priv-event_space sizeof e-event) { + spin_unlock_irqrestore(dev-event_lock, flags); + goto out; + } + file_priv-event_space -= sizeof e-event; + spin_unlock_irqrestore(dev-event_lock, flags); + + e = kzalloc(sizeof *e, GFP_KERNEL); + if (e == NULL) { + spin_lock_irqsave(dev-event_lock, flags); + file_priv-event_space += sizeof e-event; + spin_unlock_irqrestore(dev-event_lock, flags); + goto out; + } + + e-event.base.type = DRM_EVENT_VBLANK; + e-event.base.length = sizeof e-event; + e-event.user_data = page_flip-user_data; + e-base.event = e-event.base; + e-base.file_priv = file_priv; + e-base.destroy = + (void (*) (struct drm_pending_event *)) kfree; + } + + ret = crtc-funcs-page_flip(crtc, fb, e); + if (ret) { + spin_lock_irqsave(dev-event_lock, flags); + file_priv-event_space += sizeof e-event; + spin_unlock_irqrestore(dev-event_lock, flags); + kfree(e); + } + +out: + mutex_unlock(dev-mode_config.mutex); + return ret; +} diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index a75ca63..672f473 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -145,6 +145,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) diff --git a/include/drm/drm.h b/include/drm/drm.h index fa6d915..3919a4f 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -687,6 +687,7 @@ struct drm_gem_open { #define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_RMFBDRM_IOWR(0xAF, unsigned int) +#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOWR(0xB0, struct drm_mode_crtc_page_flip) /** * Device specific ioctls should only be in their respective headers diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index bfcc60d..8cf59fc 100644 --- a/include/drm/drm_crtc.h
[PATCH 2/2] Add intel implementation of the pageflip ioctl
Signed-off-by: Kristian Høgsberg k...@bitplanet.net --- drivers/gpu/drm/i915/i915_drv.h | 12 ++ drivers/gpu/drm/i915/i915_gem.c | 64 +- drivers/gpu/drm/i915/i915_irq.c | 10 ++ drivers/gpu/drm/i915/i915_reg.h |2 + drivers/gpu/drm/i915/intel_display.c | 233 +- drivers/gpu/drm/i915/intel_drv.h |3 + 6 files changed, 290 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 835625b..7c5b05e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -536,6 +536,10 @@ typedef struct drm_i915_private { /* indicate whether the LVDS_BORDER should be enabled or not */ unsigned int lvds_border_bits; + struct drm_crtc *plane_to_crtc_mapping[2]; + struct drm_crtc *pipe_to_crtc_mapping[2]; + wait_queue_head_t pending_flip_queue; + /* Reclocking support */ bool render_reclock_avail; bool lvds_downclock_avail; @@ -635,6 +639,13 @@ struct drm_i915_gem_object { * Advice: are the backing pages purgeable? */ int madv; + + /** +* Number of crtcs where this object is currently the fb, but +* will be page flipped away on the next vblank. When it +* reaches 0, dev_priv-pending_flip_queue will be woken up. +*/ + atomic_t pending_flip; }; /** @@ -826,6 +837,7 @@ void i915_gem_free_all_phys_object(struct drm_device *dev); int i915_gem_object_get_pages(struct drm_gem_object *obj); void i915_gem_object_put_pages(struct drm_gem_object *obj); void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); +void i915_gem_object_flush_write_domain(struct drm_gem_object *obj); void i915_gem_shrinker_init(void); void i915_gem_shrinker_exit(void); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2065b8f..22dd6c3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2771,6 +2771,22 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) old_write_domain); } +void +i915_gem_object_flush_write_domain(struct drm_gem_object *obj) +{ + switch (obj-write_domain) { + case I915_GEM_DOMAIN_GTT: + i915_gem_object_flush_gtt_write_domain(obj); + break; + case I915_GEM_DOMAIN_CPU: + i915_gem_object_flush_cpu_write_domain(obj); + break; + default: + i915_gem_object_flush_gpu_write_domain(obj); + break; + } +} + /** * Moves a single object to the GTT read, and possibly write domain. * @@ -3536,6 +3552,41 @@ i915_gem_check_execbuffer (struct drm_i915_gem_execbuffer *exec, return 0; } +static int +i915_gem_wait_for_pending_flip(struct drm_device *dev, + struct drm_gem_object **object_list, + int count) +{ + drm_i915_private_t *dev_priv = dev-dev_private; + struct drm_i915_gem_object *obj_priv; + DEFINE_WAIT(wait); + int i, ret = 0; + + for (;;) { + prepare_to_wait(dev_priv-pending_flip_queue, + wait, TASK_INTERRUPTIBLE); + for (i = 0; i count; i++) { + obj_priv = object_list[i]-driver_private; + if (atomic_read(obj_priv-pending_flip) 0) + break; + } + if (i == count) + break; + + if (!signal_pending(current)) { + mutex_unlock(dev-struct_mutex); + schedule(); + mutex_lock(dev-struct_mutex); + continue; + } + ret = -ERESTARTSYS; + break; + } + finish_wait(dev_priv-pending_flip_queue, wait); + + return ret; +} + int i915_gem_execbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -3551,7 +3602,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, int ret, ret2, i, pinned = 0; uint64_t exec_offset; uint32_t seqno, flush_domains, reloc_index; - int pin_tries; + int pin_tries, flips; #if WATCH_EXEC DRM_INFO(buffers_ptr %d buffer_count %d len %08x\n, @@ -3623,6 +3674,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, } /* Look up object handles */ + flips = 0; for (i = 0; i args-buffer_count; i++) { object_list[i] = drm_gem_object_lookup(dev, file_priv, exec_list[i].handle); @@ -3641,6 +3693,14 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, goto err; } obj_priv
Re: [PATCH] drm/i915: Add page flipping ioctl
2009/11/12 Jakob Bornecrantz ja...@vmware.com: On 12 nov 2009, at 17.44, Kristian Høgsberg wrote: This adds a page flipping ioctl to the KMS API. The ioctl takes an fb ID and a ctrc ID and flips the crtc to the given fb at the next vblank. The ioctl returns immediately but the flip doesn't happen until after any rendering that's currently queued up against the new framebuffer is done. After submitting a page flip, any execbuffer involving the old front buffer will block until the flip is completed. Optionally, a vblank event can be generated when the swap eventually happens. Signed-off-by: Kristian Høgsberg k...@bitplanet.net Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- Okay, here we go again. Page flip ioctl, this time, with blocking in the kernel and optional events to userspace. Blocking in the kernel doesn't hold any locks and lets other processes use the GPU while we're waiting for the flip to finish. cheers, Kristian Cool stuff! You have my Acked-by: Jakob Bornecrantz ja...@vmware.com if you fix a couple of things in the patch (mostly docu). Can you describes what happens if userspace continues to submit command to the pending buffer? Does it block, does the flip get delayed, or will it complete as soon as the commands that where pending at page_flip ioctl time? What happens if I try to use the old framebuffer as a source? What happens if I submit a new page_flip before the old one completes? Twenty questions I know but I just want what happens to be well documented, not just in this email thread but in actually source as well. So we can say use the source Luke with good conscience. Cool, thanks. Good points, I'll update the patch with documentation as you suggest. cheers, Kristian drivers/gpu/drm/drm_crtc.c | 69 ++ drivers/gpu/drm/drm_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 11 ++ drivers/gpu/drm/i915/i915_gem.c | 63 +- drivers/gpu/drm/i915/i915_irq.c | 10 ++ drivers/gpu/drm/i915/i915_reg.h | 2 + drivers/gpu/drm/i915/intel_display.c | 232 +- drivers/gpu/drm/i915/intel_drv.h | 3 + include/drm/drm.h | 1 + include/drm/drm_crtc.h | 8 ++ include/drm/drm_mode.h | 11 ++ 11 files changed, 378 insertions(+), 33 deletions(-) [SNIP] /** * Device specific ioctls should only be in their respective headers diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index bfcc60d..7df8af2 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -290,6 +290,7 @@ struct drm_property { struct drm_crtc; struct drm_connector; struct drm_encoder; +struct drm_pending_vblank_event; /** * drm_crtc_funcs - control CRTCs for a given device @@ -333,6 +334,11 @@ struct drm_crtc_funcs { void (*destroy)(struct drm_crtc *crtc); int (*set_config)(struct drm_mode_set *set); + + /* Flip to the given framebuffer on next vblank */ + int (*page_flip)(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event); }; The documentation here doesn't describe the stuff that is hard to get about the page_flip behavior. Like the blocking draw commands on the old framebuffer until the flip completes, that it should return immediate and so on. Please add that. /** @@ -757,6 +763,8 @@ extern int drm_mode_gamma_get_ioctl(struct drm_device *dev, extern int drm_mode_gamma_set_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); extern bool drm_detect_hdmi_monitor(struct edid *edid); +extern int drm_mode_page_flip_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); extern struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, int vdisplay, int vrefresh, bool reduced, bool interlaced, bool margins); diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index 1f90841..bcabc17 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -268,4 +268,15 @@ struct drm_mode_crtc_lut { __u64 blue; }; Same here, can you please describe the side effects are of the ioctl? I know that none of the other ioctl's have this kind of docu, but my feeling is that we are in the get_resources does probe boat because of that, and I hate to see it again. Something like: /* * KMS page flip ioctl, providing cool tearfree flipping since 2009. * * Flips between to a new framebuffer at vblank time, the ioctl will * only schedule a flip and returns immediate. An event will be * generated if the PAGE_FLIP_EVENT flag is set, see ??. * * Submitting a new page flip before the next one completes causes ??. * * Side effects: * Page flip
Re: [PATCH] drm/i915: Add page flipping ioctl
2009/11/14 Thomas Hellström tho...@shipmail.org: Kristian Høgsberg wrote: This adds a page flipping ioctl to the KMS API. The ioctl takes an fb ID and a ctrc ID and flips the crtc to the given fb at the next vblank. The ioctl returns immediately but the flip doesn't happen until after any rendering that's currently queued up against the new framebuffer is done. After submitting a page flip, any execbuffer involving the old front buffer will block until the flip is completed. Optionally, a vblank event can be generated when the swap eventually happens. Signed-off-by: Kristian Høgsberg k...@bitplanet.net Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- Okay, here we go again. Page flip ioctl, this time, with blocking in the kernel and optional events to userspace. Blocking in the kernel doesn't hold any locks and lets other processes use the GPU while we're waiting for the flip to finish. cheers, Kristian drivers/gpu/drm/drm_crtc.c | 69 ++ drivers/gpu/drm/drm_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 11 ++ drivers/gpu/drm/i915/i915_gem.c | 63 +- drivers/gpu/drm/i915/i915_irq.c | 10 ++ drivers/gpu/drm/i915/i915_reg.h | 2 + drivers/gpu/drm/i915/intel_display.c | 232 +- drivers/gpu/drm/i915/intel_drv.h | 3 + include/drm/drm.h | 1 + include/drm/drm_crtc.h | 8 ++ include/drm/drm_mode.h | 11 ++ 11 files changed, 378 insertions(+), 33 deletions(-) Kristian, Acked by me as well, but I agree with Jakob's comments on the documentation of the semantics. Perhaps split into a drm and an i915 part? Great, thanks. Yeah, splitting it will make it more clear where the drm/chipset boundary is. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm/i915: Add page flipping ioctl
This adds a page flipping ioctl to the KMS API. The ioctl takes an fb ID and a ctrc ID and flips the crtc to the given fb at the next vblank. The ioctl returns immediately but the flip doesn't happen until after any rendering that's currently queued up against the new framebuffer is done. After submitting a page flip, any execbuffer involving the old front buffer will block until the flip is completed. Optionally, a vblank event can be generated when the swap eventually happens. Signed-off-by: Kristian Høgsberg k...@bitplanet.net Reviewed-by: Chris Wilson ch...@chris-wilson.co.uk --- Okay, here we go again. Page flip ioctl, this time, with blocking in the kernel and optional events to userspace. Blocking in the kernel doesn't hold any locks and lets other processes use the GPU while we're waiting for the flip to finish. cheers, Kristian drivers/gpu/drm/drm_crtc.c | 69 ++ drivers/gpu/drm/drm_drv.c|1 + drivers/gpu/drm/i915/i915_drv.h | 11 ++ drivers/gpu/drm/i915/i915_gem.c | 63 +- drivers/gpu/drm/i915/i915_irq.c | 10 ++ drivers/gpu/drm/i915/i915_reg.h |2 + drivers/gpu/drm/i915/intel_display.c | 232 +- drivers/gpu/drm/i915/intel_drv.h |3 + include/drm/drm.h|1 + include/drm/drm_crtc.h |8 ++ include/drm/drm_mode.h | 11 ++ 11 files changed, 378 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index ee0cde1..ac2fa19 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2479,3 +2479,72 @@ out: mutex_unlock(dev-mode_config.mutex); return ret; } + +int drm_mode_page_flip_ioctl(struct drm_device *dev, +void *data, struct drm_file *file_priv) +{ + struct drm_mode_crtc_page_flip *page_flip = data; + struct drm_mode_object *obj; + struct drm_crtc *crtc; + struct drm_framebuffer *fb; + struct drm_pending_vblank_event *e = NULL; + unsigned long flags; + int ret = -EINVAL; + + if (page_flip-flags ~DRM_MODE_PAGE_FLIP_FLAGS || + page_flip-reserved != 0) + return -EINVAL; + + mutex_lock(dev-mode_config.mutex); + obj = drm_mode_object_find(dev, page_flip-crtc_id, DRM_MODE_OBJECT_CRTC); + if (!obj) + goto out; + crtc = obj_to_crtc(obj); + + if (crtc-funcs-page_flip == NULL) + goto out; + + obj = drm_mode_object_find(dev, page_flip-fb_id, DRM_MODE_OBJECT_FB); + if (!obj) + goto out; + fb = obj_to_fb(obj); + + if (page_flip-flags DRM_MODE_PAGE_FLIP_EVENT) { + ret = -ENOMEM; + spin_lock_irqsave(dev-event_lock, flags); + if (file_priv-event_space sizeof e-event) { + spin_unlock_irqrestore(dev-event_lock, flags); + goto out; + } + file_priv-event_space -= sizeof e-event; + spin_unlock_irqrestore(dev-event_lock, flags); + + e = kzalloc(sizeof *e, GFP_KERNEL); + if (e == NULL) { + spin_lock_irqsave(dev-event_lock, flags); + file_priv-event_space += sizeof e-event; + spin_unlock_irqrestore(dev-event_lock, flags); + goto out; + } + + e-event.base.type = DRM_EVENT_VBLANK; + e-event.base.length = sizeof e-event; + e-event.user_data = page_flip-user_data; + e-base.event = e-event.base; + e-base.file_priv = file_priv; + e-base.destroy = + (void (*) (struct drm_pending_event *)) kfree; + } + + ret = crtc-funcs-page_flip(crtc, fb, e); + if (ret) { + spin_lock_irqsave(dev-event_lock, flags); + file_priv-event_space += sizeof e-event; + spin_unlock_irqrestore(dev-event_lock, flags); + kfree(e); + } + +out: + mutex_unlock(dev-mode_config.mutex); + return ret; +} diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index a75ca63..672f473 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -145,6 +145,7 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_PAGE_FLIP, drm_mode_page_flip_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), }; #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls ) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 835625b..f5425cc
Re: [RFC] DRI2 synchronization and swap bits
On Fri, Oct 30, 2009 at 1:42 PM, Eric Anholt e...@anholt.net wrote: On Fri, 2009-10-30 at 10:59 -0700, Jesse Barnes wrote: I've put up some trees (after learning my lesson about working in the main tree) with the latest DRI2 sync/swap bits: git://git.freedesktop.org/home/jbarnes/xserver master branch git://git.freedesktop.org/home/jbarnes/mesa master branch They includes support for some new DRI2 requests (proto for which is in the dri2-swapbuffers branch of dri2proto), including: DRI2SwapBuffers DRI2GetMSC DRI2WaitMSC and DRI2WaitSBC These allow us to support GLX extensions like SGI_video_sync, OML_swap_control and SGI_swap_interval. There have been a few comments about the protocol so far: 1) DRI2SwapBuffers a) Concern about doing another round trip to fetch new buffers following the swap. I think this is a valid concern, we could potentially respond from the swap with the new buffers, but this would make some memory saving optimizations more difficult (e.g. freeing buffers if no drawing comes in for a short time after the swap). You're doing one round-trip anyway, and if users are concerned about the second one, go use XCB already. (We need to go fix Mesa to do that). DRI2SwapBuffers is a one-way request, but it's required to follow up with a DRI2GetBuffers. So it's only one round trip whether we use XCB or not. cheers, Kristian -- Come build with us! The BlackBerry(R) Developer Conference in SF, CA is the only developer event you need to attend this year. Jumpstart your developing skills, take BlackBerry mobile applications to market and stay ahead of the curve. Join us from November 9 - 12, 2009. Register now! http://p.sf.net/sfu/devconference -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] drm: Add async event synchronization for drmWaitVblank
This patch adds a new flag to the drmWaitVblank ioctl, which asks the drm to return immediately and notify userspace when the specified vblank sequence happens by sending an event back on the drm fd. The event mechanism works with the other flags supported by the ioctls, specifically, the vblank sequence can be specified relatively or absolutely, and works for primary and seconday crtc. The signal field of the vblank request is used to provide user data, which will be sent back to user space in the vblank event. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_fops.c | 99 ++- drivers/gpu/drm/drm_irq.c | 95 + drivers/gpu/drm/drm_stub.c |2 + drivers/gpu/drm/i915/i915_drv.c |1 + include/drm/drm.h | 33 - include/drm/drmP.h | 26 ++ 6 files changed, 252 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 251bc0e..8430e13 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -257,6 +257,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp, INIT_LIST_HEAD(priv-lhead); INIT_LIST_HEAD(priv-fbs); + INIT_LIST_HEAD(priv-event_list); + init_waitqueue_head(priv-event_wait); + priv-event_space = 4096; /* set aside 4k for event buffer */ if (dev-driver-driver_features DRIVER_GEM) drm_gem_open(dev, priv); @@ -413,6 +416,30 @@ static void drm_master_release(struct drm_device *dev, struct file *filp) } } +static void drm_events_release(struct drm_file *file_priv) +{ + struct drm_device *dev = file_priv-minor-dev; + struct drm_pending_event *e, *et; + struct drm_pending_vblank_event *v, *vt; + unsigned long flags; + + spin_lock_irqsave(dev-event_lock, flags); + + /* Remove pending flips */ + list_for_each_entry_safe(v, vt, dev-vblank_event_list, base.link) + if (v-base.file_priv == file_priv) { + list_del(v-base.link); + drm_vblank_put(dev, v-pipe); + v-base.destroy(v-base); + } + + /* Remove unconsumed events */ + list_for_each_entry_safe(e, et, file_priv-event_list, link) + e-destroy(e); + + spin_unlock_irqrestore(dev-event_lock, flags); +} + /** * Release file. * @@ -451,6 +478,8 @@ int drm_release(struct inode *inode, struct file *filp) if (file_priv-minor-master) drm_master_release(dev, filp); + drm_events_release(file_priv); + if (dev-driver-driver_features DRIVER_GEM) drm_gem_release(dev, file_priv); @@ -544,9 +573,75 @@ int drm_release(struct inode *inode, struct file *filp) } EXPORT_SYMBOL(drm_release); -/** No-op. */ +static bool +drm_dequeue_event(struct drm_file *file_priv, + size_t total, size_t max, struct drm_pending_event **out) +{ + struct drm_device *dev = file_priv-minor-dev; + struct drm_pending_event *e; + unsigned long flags; + bool ret = false; + + spin_lock_irqsave(dev-event_lock, flags); + + *out = NULL; + if (list_empty(file_priv-event_list)) + goto out; + e = list_first_entry(file_priv-event_list, +struct drm_pending_event, link); + if (e-event-length + total max) + goto out; + + file_priv-event_space += e-event-length; + list_del(e-link); + *out = e; + ret = true; + + out: + spin_unlock_irqrestore(dev-event_lock, flags); + + return ret; +} + +ssize_t drm_read(struct file *filp, char __user *buffer, +size_t count, loff_t *offset) +{ + struct drm_file *file_priv = filp-private_data; + struct drm_pending_event *e; + size_t total; + ssize_t ret; + + ret = wait_event_interruptible(file_priv-event_wait, + !list_empty(file_priv-event_list)); + if (ret 0) + return ret; + + total = 0; + while (drm_dequeue_event(file_priv, total, count, e)) { + if (copy_to_user(buffer + total, +e-event, e-event-length)) { + total = -EFAULT; + break; + } + + total += e-event-length; + e-destroy(e); + } + + return total; +} +EXPORT_SYMBOL(drm_read); + unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) { - return 0; + struct drm_file *file_priv = filp-private_data; + unsigned int mask = 0; + + poll_wait(filp, file_priv-event_wait, wait); + + if (!list_empty(file_priv-event_list)) + mask |= POLLIN | POLLRDNORM; + + return mask
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
Thomas, What you describe sounds reasonable and I'll look into updating the patch. I'm not too keen on the driver specific flag you suggest, since it makes it hard to use the ioctl in generic code. Maybe drivers that can do pageflip from one of several fifos can expose a driver specific ioctl to configure which one should be used. I don't imagine it's something that will change much? cheers, Kristiain 2009/8/30 Thomas Hellström tho...@shipmail.org: Thomas Hellström skrev: I described this in more detail and hopefully more coherently in my email to Michel. If that's still not clear, follow up there. I've read the mail and understand the proposal, thanks. /Thomas So, I've been doing some thinking over the weekend and here's a constructive proposal that hopefully can be the base of an agreement: 1) We require the semantics of the pageflip ioctl to be such that it is safe to schedule render commands that reference the buffers involved immediately after the ioctl return, or in other words, the pageflip has entered the graphics pipeline and any render operations to the referenced buffers will be guaranteed to be executed after the pageflip. How this is implemented is up to the driver, and thus the code will need driver-specific hooks. There is a multitude of ways to implement this, ranging from full hardware support to a real naive and stupid software implementation that blocks all command submission while there are pending flips. A simple sufficient implementation is to scan the buffers to be validated at cs time to see if there are pending pageflips on any of them. In that case, release all held cs locks and block. When the pageflip happens, continue. But again, that will be up to the driver. 2) We rip the blocking code out of the DRI2 protocol, since there is no longer any need for it. 3) The DRM event mechanism stays as proposed, The ioctl caller needs to explicitly request an event to get one. Events will initially be used by clients to wake _themselves_ from voluntary select() blocking. The motivation for 1-2 is as follows: a) The solution fits all kinds of smart hardware and cs mechanism, whereas the DRI2 blocking solution assumes a simple hardware and a naive kernel cs mechanism. One can argue that smart kernel schedulers or advanced hardware can work around the DRI2 blocking solution by sending out the event immediately, but there we are again working around the DRI2 blocking solution. We shouldn't need to do that. b) There's no requirement on masters to do scheduling with this proposal. Otherwise we'd have to live with that forever and implement it in all masters utilizing the pageflip ioctl. c) latency - performance. Consider the sequence of events between the vsync and the first set of rendering commands on the next frame being submit to the hardware: c1) DRI2 blocking: (Please correct me if I misunderstood something here) * vsync irq * schedule a wq thread that adds an event and wakes the X server. * X server issues a syscall to read the drm event * X server returns an event to the client with the new buffers. (write to socket ?) * Client reads the event (read from socket ?) * Client prepares the first command buffer (this is usually quite time consuming and in effect not only synchronizes GPU and command buffer building, but in effect serializes them). * Client builds and issues a cs ioctl. * Kernel submits commands to hardware. c2) Kernel scheduling (this proposal). * vsync irq * schedule the client thread that immediately submits commands to hardware. IMHO, c1 is far from optimal and should not be considered. One can argue once again, that this doesn't add much latency in practice, but we can't keep arguing like that for every such item we add per frame, and in this case the serialized command buffer building *does* add too much latency. We should seek and implement the optimal solution if it doesn't imply too much work or have side-effects. Some added functionality we should also perhaps consider adding to the ioctl interface: 1) A flag whether to vsync or not. Ideally a driconf option so that should perhaps be communicated as part of dri2 swapbuffers as well. I guess on Intel hardware you can only flip on vsync(?) but on some other hardware you can just send a new scanout startaddress down the FIFO. You'll definitely see tearing, though. 2) Driver private data. An example: Drivers with multiple hardware FIFOs that can do pageflipping and barriers on each FIFO might want to indicate to the kernel on which FIFO or HW context to schedule the pageflip. I guess this private data might also need to be passed along with dri2 swapbuffers. Thanks, /Thomas -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Fri, Aug 28, 2009 at 5:19 AM, Michel Dänzermic...@daenzer.net wrote: On Thu, 2009-08-27 at 17:33 -0400, Kristian Høgsberg wrote: 2009/8/27 Thomas Hellström tho...@shipmail.org: b) It requires the master to act as a scheduler, and circumvents the DRM command submission mechanism through the delayed unpin callback. If this is to workaround any inability of GEM to serve a command submission while a previous command submission is blocked in the kernel, then IMHO that should be fixed and not worked around. It's not about workarounds. Your suggestion *blocks the hw* while waiting for vsync. My patch doesn't do that, it lets other clients submit rendering to pixmap or backbuffer BOs that aren't involved in the pending page flip. If you're willing to block the command stream, GEM can keep the buffer pinned for you until the swap happens just fine. Just like it does for any other command - it's not about that. In fact, I think using the scheduler to keep buffers pinned for scanout is conflating things. The scheduler pulls buffers in and out of the aperture so that they are there for the GPU when it needs to access them. Pinning and unpinning buffers for scanout is a different matter. How is scanout not GPU access? :) I'd look at it the other way around: pinning a scanout buffer is a workaround which is only needed while there are no outstanding fences on it. I guess I don't see the scanout engine as part of the GPU. If you think pinning a scanout buffer is a workaround, how do you propose we keep it in the aperture? Using a special fence class that never expire? Isn't that what pinning is? If the plan is to eliminate DRI2GetBuffers() once per frame, what will then be used to block clients rendering to the old back buffer? There'll be an event that's sent back after each DRI2SwapBuffer and the clients will block on receiving that event. Are you referring to a DRI2 protocol event or a DRM event? Sorry, a DRI2 event. We still need to send a request to the xserver and receive confirmation that the xserver has received it before we can render again. DRI2GetBuffers is a request that expects a reply and will block the client on the xserver when we call it. DRI2SwapBuffers is an async request, ie there's no reply and calling it wont block necessarily the client. We still have to wait for the new event before we can go on rendering, but doing it this way makes the client and server less tightly coupled. We may end up doing the roundtrip between client and server at a point where the client was going to block anyway (like disk i/o or something) saving a context switch. It's still a bit fuzzy how this is all supposed to work. To me it seems like (ab)using DRI2GetBuffers for this will only allow clients to avoid synchronous rendering with triple buffering, which would be a shame. If you disagree, can you explain why that isn't the case? The way it works is that glXSwapBuffers() will send the DRI2SwapBuffer request and return immediately. There is not response to the DRI2SwapBuffer request, so it won't block on the X server there. The application is now free to do other processing, loading a new frame of disk and decode it, for example. However, the glXSwapBuffers() call also invalidates the DRI drivers buffers, so once the application wants to render again, it has to call DRI2GetBuffers, which is a round trip, so here we'll block on the X server. This ensures that the X server has seen the DRI2SwapBuffer request before we start rendering again, and provides the application with the buffers it needs for the next frame. This last bit is important, as the server may or may not be able to do a page flip, so the client can't generally predict what the buffer to use for the next frame will be. What I'm proposing over this scheme with the DRI2 event is that instead of requiring the client to call DRI2GetBuffers, we can send out a DRI2 event once the flip happens. This breaks the required roundtrip into a one-way request and an event. Worst case, this still requires the clent to block on receiving the event. However, it also allows the X server to process the DRI2SwapBuffer request and send the event to the client before the client gets around to needing, in which case the round trip disappears. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
This mail is getting out of control... too many sub-threads going on... maybe we shold break it out and talk about events vs kernel scheduling and wait with the patch review until we've figured something out. 2009/8/28 Thomas Hellström tho...@shipmail.org: Kristian Høgsberg skrev: 2009/8/27 Thomas Hellström tho...@shipmail.org: Kristian Høgsberg skrev: --- Okay, here's the patch again with the locking fixed. Everything else is the same. As for the potential problem with polling on the drm fd with both dri1 and dri2 enabled, I suggest that we just disable the dri1 sigio handler in the xserver. We'll do this in a commit that precedes the merge of the page flipping code, so that no server will be able to poll on the drm fd in both dri1 and dri2 code. cheers, Kristian Grr 1) The locking problems are still not fixed. See below. I just did a quick look, so the comment list is not complete. It's not as bad as you think. There is one glitch where I changed struct_mutex to mode_config.mutex and left dev-flip_list unprotected. The other issues you comment on should be fine, I've followed up in detail below. I actually think it is. See below. /Grr Even if that is fixed, I believe this patch adds a framework that doesn't belong in a modern day graphical subsystem for the following reasons, many of them already mentioned, but let me reiterate. Although the dri1 compatibility issue will be fixed with your suggestion. a) It puts requirements on user-space for correct functionality of DRM ioctls. I'm talking about the master needing to parse the event queue. Don't we already have a lot of requirements on userspace to use the DRM? It's not exactly trivial to prepare a execbuffer ioctl, or to find a connector, crtc and mode and set that, for example. Part of this work is a new libdrm entry point to read an parse the events from the fd. See the dri2-swapbuffer branch in drm.git. b) It requires the master to act as a scheduler, and circumvents the DRM command submission mechanism through the delayed unpin callback. If this is to workaround any inability of GEM to serve a command submission while a previous command submission is blocked in the kernel, then IMHO that should be fixed and not worked around. It's not about workarounds. Your suggestion *blocks the hw* while waiting for vsync. No it doesn't. It blocks dri clients when they try to render to old fronts. Other dri clients would continue rendering. It provides a natural migration path to triple buffering where automagically nothing is blocked, and also to advanced software schedulers that can buffer command submissions instead of blocking. You advocated blocking the command queue using a wait-for-vblank command at some point. Now the concern about GEM was that if the kernel takes a global mutex _before_ blocking a client and doesn't release that mutex when the client is blocked, all rendering will naturally be blocked as a consequence. That's not how the patch works. We hold no locks while the client is blocked. What my suggestion *does* is to block the X server if AIGLX tries to render to the old front, and the command scheduler is simple. Now I'm not completely sure how serious that is, given that AIGLX will, as stated before, frequently block the X server anyway since it's not running in a separate thread. Are you talking about an AIGLX client submitting an expensive shader locking up the X server for a long time? I'm not aware of any way AIGLX can block the server for up to 20ms at a time right now, but that is what it'll do if it blocks on vsync. c) The implementation will mostly be worked around with capable schedulers and hardware. This is not about the capability of the hw or the sw. The design is deliberate. What I mean is that if I don't want the kernel code to do delayed unpins, because my cs already handles that, and I don't want the X server to block clients because my cs or hardware will handle that, I would do my very best to work around this code. I don't see the difference between a delayed unpin and a fence. We're doing the same thing, why is it ok if we call it a fence? You were saying that we should make the vsync interrupt look like a sw command queue and use that to fence the scan-out buffer right? Is that really better? I feel a bit like we're getting dragged back into the GEM vs TTM discussion here. I have no stake in that battle, I'm just trying to work with what's there. I don't think there's a fundamental problem nor benefit with either, and what you can do with a TTM fence you can do by waiting on the right GEM BO, as far as I understand. A couple of questions: Why are you guys so reluctant to use kernel scheduling for this instead of a mix of kernel / user-space scheduling? I'm not opposed to kernel scheduling as well, but userspace needs this event. I've made the case for AIGLX in the X server already
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
2009/8/27 Thomas Hellström tho...@shipmail.org: Kristian Høgsberg skrev: --- Okay, here's the patch again with the locking fixed. Everything else is the same. As for the potential problem with polling on the drm fd with both dri1 and dri2 enabled, I suggest that we just disable the dri1 sigio handler in the xserver. We'll do this in a commit that precedes the merge of the page flipping code, so that no server will be able to poll on the drm fd in both dri1 and dri2 code. cheers, Kristian Grr 1) The locking problems are still not fixed. See below. I just did a quick look, so the comment list is not complete. It's not as bad as you think. There is one glitch where I changed struct_mutex to mode_config.mutex and left dev-flip_list unprotected. The other issues you comment on should be fine, I've followed up in detail below. 2) The 64/32-bit EFAULT problems mentioned are ignored. See below. Not ignored, they were good comments, I just forgot about them in the heat of the discussion. I'll pad the structs. /Grr Even if that is fixed, I believe this patch adds a framework that doesn't belong in a modern day graphical subsystem for the following reasons, many of them already mentioned, but let me reiterate. Although the dri1 compatibility issue will be fixed with your suggestion. a) It puts requirements on user-space for correct functionality of DRM ioctls. I'm talking about the master needing to parse the event queue. Don't we already have a lot of requirements on userspace to use the DRM? It's not exactly trivial to prepare a execbuffer ioctl, or to find a connector, crtc and mode and set that, for example. Part of this work is a new libdrm entry point to read an parse the events from the fd. See the dri2-swapbuffer branch in drm.git. b) It requires the master to act as a scheduler, and circumvents the DRM command submission mechanism through the delayed unpin callback. If this is to workaround any inability of GEM to serve a command submission while a previous command submission is blocked in the kernel, then IMHO that should be fixed and not worked around. It's not about workarounds. Your suggestion *blocks the hw* while waiting for vsync. My patch doesn't do that, it lets other clients submit rendering to pixmap or backbuffer BOs that aren't involved in the pending page flip. If you're willing to block the command stream, GEM can keep the buffer pinned for you until the swap happens just fine. Just like it does for any other command - it's not about that. In fact, I think using the scheduler to keep buffers pinned for scanout is conflating things. The scheduler pulls buffers in and out of the aperture so that they are there for the GPU when it needs to access them. Pinning and unpinning buffers for scanout is a different matter. c) The implementation will mostly be worked around with capable schedulers and hardware. This is not about the capability of the hw or the sw. The design is deliberate. A couple of questions: Why are you guys so reluctant to use kernel scheduling for this instead of a mix of kernel / user-space scheduling? I'm not opposed to kernel scheduling as well, but userspace needs this event. I've made the case for AIGLX in the X server already, and direct rendering clients (for example, compositors) that want to handle input for as long as possible and avoid blocking has the same needs. If the plan is to eliminate DRI2GetBuffers() once per frame, what will then be used to block clients rendering to the old back buffer? There'll be an event that's sent back after each DRI2SwapBuffer and the clients will block on receiving that event. We still need to send a request to the xserver and receive confirmation that the xserver has received it before we can render again. DRI2GetBuffers is a request that expects a reply and will block the client on the xserver when we call it. DRI2SwapBuffers is an async request, ie there's no reply and calling it wont block necessarily the client. We still have to wait for the new event before we can go on rendering, but doing it this way makes the client and server less tightly coupled. We may end up doing the roundtrip between client and server at a point where the client was going to block anyway (like disk i/o or something) saving a context switch. drivers/gpu/drm/drm_crtc.c | 171 ++- drivers/gpu/drm/drm_crtc_helper.c | 10 ++ drivers/gpu/drm/drm_drv.c | 1 + drivers/gpu/drm/drm_fops.c | 68 - drivers/gpu/drm/drm_irq.c | 42 drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/intel_display.c | 16 +++- drivers/gpu/drm/radeon/radeon_display.c | 3 +- include/drm/drm.h | 25 + include/drm/drmP.h | 32 ++ include/drm/drm_crtc.h | 27 + include/drm
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
I'm a little fuzzy on the details, this part of the patch was carried over from Jesse's original work. I believe set_base is supposed to be called with the struct mutex held. We shouldn't be this sloppy about locking, and in particular we shouldn't protect a callback with a lock without knowing why. A lock should protect data, not serialize calls to functions, and it should ideally be documented somewhere. Why does set_base need the _caller_ to take the struct_mutex lock? Are there more driver callbacks that need the struct_mutex held? I mean if I implement a modesetting driver that takes care to use device private locks not visible to the caller to avoid polluting the struct_mutex with possible contention and lockdep errors as a result, I'd still find the generic code taking the struct_mutex for me becase it assumes that I need it? This can't be right and should go away. Good point, I'll take a closer look and figure out what the locking should be like. Perhaps TTM bo read/write could use ioctls like the gem pwrite/pread ioctls? The only way we can get asynchronous notifications from the drm to userspace is through readable events on the drm fd. How were you planning to implement read and write from multiple bo's through one fd anyway? Reusing the fake offset we use for mmap? I think the ioctl approach is cleaner since you can just pass in the object handle and the offset into the object. Maybe even add src and dst stride arguments. It's a common misconception that the TTM bo offsets are fake offsets from outer space. The offsets aren't fake offsets but real offsets into the device address space, so a logical consequence of mapping a part of that address space is to be able to read and write to the same address space, That is read / write implemented using syscalls as intended. That said, rectangular bo blit ioctls is probably a good idea as well, and some drivers, like via, already have them. I don't know that we need a separate char device or that read/write was intended for accessing buffer data. We already have lots of different, unrelated ioclts on the fd - I see it more as a IPC mechanism between kernel and userspace, A couple of years ago, any attempt to return anything else than 0 from drm poll resulted in an X server error. http://freedesktop.org/bugzilla/show_bug.cgi?id=1505. The fix mentioned in the bug was actually to return 0 from drm poll, and a comment about this is still present in drm.git. The above breaks drm for old X servers and all drivers, which I think is against drm policy? That can't be the real problem. The X server polls on a ton of file descriptors already; sockets from clients, dbus, input devices. They all have poll implementations that don't return 0... I mean, otherwise they wouldn't work. Look at evdev_poll() in drivers/input/evdev.c for the evdev poll implementation, for example. You're probably right, but we should probably find out what went wrong and make sure it doesn't happen again with non-modesetting drivers + dri1 before pushing this. I really don't think that's necessary. As I wrote in my reply to Dave, there's nothing in this patch that can cause select(2) to return EINVAL that isn't already present in other poll fops implementations. Like the evdev one, which we already select on - please compare that function with the poll implementation in my patch and tell me why the drm poll is cause for concern. I need a better, more specific reason why this is such a risk and why I should spend more time tracking this stuff down. And if select(2), for whatever reason, returns EINVAL because of the drm_poll() fops implementation, that's a bug in the kernel that needs to be fixed. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Tue, Aug 18, 2009 at 3:52 AM, Thomas Hellströmtho...@shipmail.org wrote: Kristian Høgsberg wrote: By sending an event back on the file descriptor we allow users of the API to wait on the flip to finish in a standard poll or select mainloop, where it can handle input from other sources while waiting. If you rely on fences, the application will block when it tries to access the buffers protected by the fence, and is unable to handle input from other sources while it's blocking. Yes. you're right. How is the flip_finished event typically used by user space? Is it mostly for convenience or is it a must have? In the server we use the event to wake up the client who calls glXSwapBuffer(). We block the client (SuspendClient) if it tries to draw before the swap is complete and wake it up again when we get the event from drm. See the dri2-swapbuffers branch in xorg/xserver git for details. Even with the vsync barrier in the command stream (which intel hw also supports) you do need to keep the current front buffer pinned for the remainder of the frame, and then you need notification when the swap has happened so that you can unpin the old buffer. That would be taken care of by fences (see previous mail), but that's merely a terminology thing. The big difference is that the driver would handle that synchronization as part of command submission. Right, but you'll still need an interrupt inside the drm driver to let you know that the vblank barrier has been processed so you can clear the fence. I'm sure Unichrome has a command to send an interrupt, which can be queued after the vsync barrier to run the workqueue and trigger this cleanup as well as sending the userspace notification. Actually it hasn't (stupid hardware), so a medium frequency polling scheme needs to be used for most GPU waiting. So the user-space notification would require some additional thoughts but nothing that can't be implemented when the need for it arises. Yikes. Is there a way to at least get a timestamp from the hw at the time the swap happens? cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Tue, Aug 18, 2009 at 2:08 AM, Thomas Hellströmtho...@shipmail.org wrote: Kristian Høgsberg wrote: Perhaps TTM bo read/write could use ioctls like the gem pwrite/pread ioctls? The only way we can get asynchronous notifications from the drm to userspace is through readable events on the drm fd. How were you planning to implement read and write from multiple bo's through one fd anyway? Reusing the fake offset we use for mmap? I think the ioctl approach is cleaner since you can just pass in the object handle and the offset into the object. Maybe even add src and dst stride arguments. It's a common misconception that the TTM bo offsets are fake offsets from outer space. The offsets aren't fake offsets but real offsets into the device address space, so a logical consequence of mapping a part of that address space is to be able to read and write to the same address space, That is read / write implemented using syscalls as intended. That said, rectangular bo blit ioctls is probably a good idea as well, and some drivers, like via, already have them. But I do think that if we claim device reads and writes for modesetting, we should move bo IO to another device to be consistent. Oh, to this last paragraph I wanted to point out that the drm fd event isn't modesetting specific. It's a generic event mechanism that we can use for other cases. For example, an asynchronous glReadPixels/DownloadFromScreen ioctls, or a breadcrumb ioctl that sends an event back once the command processor has caught up. The event structure has a header like this: struct drm_event { __u32 type; __u32 length; }; which lets us introduce new types of events and lets an older userspace skip unknown events. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Tue, Aug 18, 2009 at 1:36 PM, Thomas Hellströmtho...@shipmail.org wrote: Kristian Høgsberg wrote: On Tue, Aug 18, 2009 at 3:52 AM, Thomas Hellströmtho...@shipmail.org wrote: Kristian Høgsberg wrote: By sending an event back on the file descriptor we allow users of the API to wait on the flip to finish in a standard poll or select mainloop, where it can handle input from other sources while waiting. If you rely on fences, the application will block when it tries to access the buffers protected by the fence, and is unable to handle input from other sources while it's blocking. Yes. you're right. How is the flip_finished event typically used by user space? Is it mostly for convenience or is it a must have? In the server we use the event to wake up the client who calls glXSwapBuffer(). We block the client (SuspendClient) if it tries to draw before the swap is complete and wake it up again when we get the event from drm. See the dri2-swapbuffers branch in xorg/xserver git for details. So in the case where you have the command submission inserting relevant barriers (like hardware barriers in the Unichrome case, or fence class barriers in the general TTM fence-aware driver case, this notification is not really necessary since the flip is guaranteed to happen before any other rendering commands that touch the buffers in question. So modulo the flip timing notifications, the flip_finished event can be sent already when the flip is scheduled. Are the flip timing notifications required to be accurate? If so we have a slight problem, because we don't unnecessarily want to put clients to sleep, and we don't know when the flip has happened until it has actually happened. We don't put clients to sleep until they try to render to the new backbuffer. For direct rendering this happens when the client calls DRI2GetBuffers() after having called DRI2SwapBuffers(). If the flip is not yet finished at that time, we restart the X request and suspend the client. When the drm event fires it is read by the ddx driver, which then calls DRI2SwapComplete() which will wake the client up again. For AIGLX, we suspend the client in __glXForceCurrent(), but the wakeup happens the same way. Either way, for DRI2 the notification doesn't need to be accurate, but the later we send it, the later we wake up the client, the less time the client will have to render the next frame. Of course, if you're willing to block the command queue on the flip, you can send the event as soon as the vsync barrier and swap commands have been queued and everything should be fine. But with the drm event, we have the option of not blocking the hw queue on the flip for hw that lets us do vsynced page flips outside the command queue (on intel hw it's just a register write, and the hw latches the new address and loads it on the next vsync). Does your hw not have a vsync interrupt either? We don't fire an interrupt from the command queue, we just program the flip and then send the event from the vsync interrup. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Tue, Aug 18, 2009 at 5:03 PM, Dave Airlieairl...@gmail.com wrote: On Wed, Aug 19, 2009 at 2:12 AM, Keith Whitwellkei...@vmware.com wrote: I think the bug in question was because somebody (Jon Smirl??) removed the empty apparently unused poll implementation from the drm fd, only to discover that the X server was actually polling the fd. If this code adds to, extends or at least doesn't remove the ability to poll the drm fd, it should be fine. You have a better memory than me, but thats exactly what happened alright. And in the meantime I did dig up the story of the poll implementation in drm. I'm guessing the trouble started when Jon Smirl removed the drm_poll implementation that returned 0 in 3aef3841d0c8099a97a56a285f0a21d9147405bd. The default behaviour in the case of an fd with missing poll implementation is to assume always readable and writable (DEFAULT_POLLMASK). So by removing the drm_poll function the drm fd went from never selecting readable or writable to always selecting readable and writable. To fix this 5e8838fd115879174567c4c2db8ad25331619994 in drm.git and looks like this: +/** No-op. */ +/* This is to deal with older X servers that believe 0 means data is + * available which is not the correct return for a poll function. + * By alternating returns both interfaces are happy. This is fixed + * in newer X servers. + */ +unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) +{ + static int flip; + if ((flip = !flip)) + return (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM); + return 0; +} +EXPORT_SYMBOL(drm_poll); which wins the WTF of the day. It was the fixed in b974e2cd683fa798970cd1bdc5e20acfb7a34a9c where it was changed to just return 0 like before. Again, the problem was not that select returns zero, the problem was that select would error with EINVAL. I don't see any error path in do_select() in fs/select.c that could cause EINVAL based on the return value from one of the poll fops implementations. The only two cases I can think of is that either the core select implementation was different back then, for example return EINVAL if a poll fops returns 0 without registering a poll waitqueue or not having a read fops or something. However, that should still be valid and if it errors it shouldn't throw EINVAL since it's not a user error. The other theory is that since the default behaviour in case of no poll fops implementation is to return immediately (or in case of the wtf poll, to return immediately on every other select() call) always with the drm fd readable and writable, it could have triggered an overflow edge case in the poll timeout value computation. Aside from negative nfds, an invalid timeout value is the only condition that can trigger EINVAL according to the man page. That's it, I rest my case ;) Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Tue, Aug 18, 2009 at 6:12 PM, Thomas Hellströmtho...@shipmail.org wrote: Kristian Høgsberg wrote: On Tue, Aug 18, 2009 at 5:03 PM, Dave Airlieairl...@gmail.com wrote: On Wed, Aug 19, 2009 at 2:12 AM, Keith Whitwellkei...@vmware.com wrote: I think the bug in question was because somebody (Jon Smirl??) removed the empty apparently unused poll implementation from the drm fd, only to discover that the X server was actually polling the fd. If this code adds to, extends or at least doesn't remove the ability to poll the drm fd, it should be fine. You have a better memory than me, but thats exactly what happened alright. And in the meantime I did dig up the story of the poll implementation in drm. I'm guessing the trouble started when Jon Smirl removed the drm_poll implementation that returned 0 in 3aef3841d0c8099a97a56a285f0a21d9147405bd. The default behaviour in the case of an fd with missing poll implementation is to assume always readable and writable (DEFAULT_POLLMASK). So by removing the drm_poll function the drm fd went from never selecting readable or writable to always selecting readable and writable. To fix this 5e8838fd115879174567c4c2db8ad25331619994 in drm.git and looks like this: +/** No-op. */ +/* This is to deal with older X servers that believe 0 means data is + * available which is not the correct return for a poll function. + * By alternating returns both interfaces are happy. This is fixed + * in newer X servers. + */ +unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait) +{ + static int flip; + if ((flip = !flip)) + return (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM); + return 0; +} +EXPORT_SYMBOL(drm_poll); which wins the WTF of the day. It was the fixed in b974e2cd683fa798970cd1bdc5e20acfb7a34a9c where it was changed to just return 0 like before. Again, the problem was not that select returns zero, the problem was that select would error with EINVAL. I don't see any error path in do_select() in fs/select.c that could cause EINVAL based on the return value from one of the poll fops implementations. The only two cases I can think of is that either the core select implementation was different back then, for example return EINVAL if a poll fops returns 0 without registering a poll waitqueue or not having a read fops or something. However, that should still be valid and if it errors it shouldn't throw EINVAL since it's not a user error. The other theory is that since the default behaviour in case of no poll fops implementation is to return immediately (or in case of the wtf poll, to return immediately on every other select() call) always with the drm fd readable and writable, it could have triggered an overflow edge case in the poll timeout value computation. Aside from negative nfds, an invalid timeout value is the only condition that can trigger EINVAL according to the man page. That's it, I rest my case ;) Kristian Actually, looking at the dri1 code, it installs a SIGIO handler to do user-space context switches, and it's waiting for data on the drm file descriptor. Now, when the X server receives a SIGIO no matter from what client, it calls select to determine from which sigio'd file descriptor. If the drm file descriptor indicates reading would not block, it goes ahead reading data to process a context switch, which will of course be bogus data. Yes, so if we use DRI1 and DRI2 page flipping at the same time we might have a problem. If we just used DRI1, the drm fd will never select readable, if we just use DRI2, we never install the SIGIO handler. Looking way back in the drm.git history, I see that there actually used to be a drm_read() and a drm_poll(). They weren't used for reading out the contents of the buffer maps, they were for sending events to userspace. Only one event was ever supported, in the form of lines like C 5 8, meaning switch context where 5 and 8 are handles of the old and new context. So if anything, there's precedence for using the drm fd for event delivery, but of course we need to make sure we dont mix things up between DRI1 and DRI2. So as long as no DDX driver tries to support DRI1 and DRI2 at the same time I dont see a problem here. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Tue, Aug 18, 2009 at 7:12 PM, Luc Verhaegenl...@skynet.be wrote: And on the flip side of this, what you do is purely technical, always. #dri-devel 00:05 +airlied krh: you've been smirled Yeah, I was wondering about that, I thought the word was smirl-rolled :D cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Tue, Aug 18, 2009 at 6:31 PM, Thomas Hellströmtho...@shipmail.org wrote: Jesse Barnes wrote: Anyway, to me this discussion is more of a future directions one than a blocker for this particular patchset. AFAICT the only thing that needs fixing with this patch is my lock confusion (struct_mutex vs mode_config). Or would you like something substantial changed with these bits before they land? I think as long as there are efficient ways to short-circuit this implementation if the command submission mechanism does a better job, I think it's OK. I had a quick look in the new dri2 code and it looks like the driver can trick dri2 into thinking there are no outstanding swaps, thus avoiding the event reads? What's important is that the IOCTL interface gets right. Let me follow up on this tomorrow, I've used up my out-going mail quota for today. What remains to be fixed are the mutex issue and possibly the poll issue. I'll resend the patch with the mutex issue fixed. The poll issue is not a problem as long as we don't enable DRI1 and DRI2 at the same time. I also think without looking to closely that the drm_read() function doesn't do return values properly (see ldd3 and man 2 read for return values for the various blocking modes). In particular, wait_event_interruptible() may return -ERESTARTSYS which should never be returned to user-space. Returning -ERESTARTSYS from read is the expected behaviour in case you get a signal as far as I know and is handled by glibc. It's used all over the kernel. It also looks like the new ioctl argument lengths are not 64 bit aligned? Not sure what you mean... that the size of the ioctl struct isn't a multiple of 64 bits? That's not a requirement. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH 2/3] drm/ttm: Add a virtual ttm sysfs device.
On Mon, Aug 17, 2009 at 10:28 AM, Thomas Hellstromthellst...@vmware.com wrote: The device directory will be the base directory of the sysfs representation of other ttm subsystems. Signed-off-by: Thomas Hellstrom thellst...@vmware.com --- drivers/gpu/drm/ttm/ttm_module.c | 56 +- 1 files changed, 55 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_module.c b/drivers/gpu/drm/ttm/ttm_module.c index 59ce819..4197467 100644 --- a/drivers/gpu/drm/ttm/ttm_module.c +++ b/drivers/gpu/drm/ttm/ttm_module.c @@ -29,16 +29,70 @@ * Jerome Glisse */ #include linux/module.h -#include ttm/ttm_module.h +#include linux/device.h +#include linux/sched.h +#include ttm/ttm_module.h +#include drm_sysfs.h + +atomic_t device_released; + +static struct device_type ttm_drm_class_type = { + .name = ttm, + /** + * Add pm ops here. + */ +}; + +static void ttm_drm_class_device_release(struct device *dev) +{ + atomic_set(device_released, 1); +} + +static struct device ttm_drm_class_device = { + .type = ttm_drm_class_type, + .release = ttm_drm_class_device_release +}; + +struct kobject *ttm_get_kobj(void) +{ + struct kobject *kobj = ttm_drm_class_device.kobj; + BUG_ON(kobj == NULL); + return kobj; +} static int __init ttm_init(void) { + int ret; + + ret = dev_set_name(ttm_drm_class_device, ttm); + if (unlikely(ret != 0)) + return ret; + ttm_global_init(); + + atomic_set(device_released, 0); + ret = drm_class_device_register(ttm_drm_class_device); + if (unlikely(ret != 0)) + goto out_no_dev_reg; + return 0; +out_no_dev_reg: + atomic_set(device_released, 1); + ttm_global_release(); + return ret; } static void __exit ttm_exit(void) { + DECLARE_WAIT_QUEUE_HEAD_ONSTACK(exit_q); + drm_class_device_unregister(ttm_drm_class_device); + + /** + * Refuse to unload until the TTM device is released. + * Not sure this is 100% needed. + */ + + wait_event(exit_q, atomic_read(device_released) == 1); How is this supposed to work? You need to make the wait queue public so that the drm_class_device_release function can wake up waiters on the queue. The atomic is just a plain integer variable, decreasing it doesn't wake up anything. cheers, Kristian ttm_global_release(); } -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] Add modesetting pageflip ioctl and corresponding drm event
This patch adds a vblank synced pageflip ioctl for to the modesetting family of ioctls. The ioctl takes a crtc and an fb and schedules a pageflip to the new fb at the next coming vertical blank event. This feature lets userspace implement tear-free updating of the screen contents with hw-guaranteed low latency page flipping. The ioctl is asynchronous in that it returns immediately and then later notifies the client by making an event available for reading on the drm fd. This lets applications add the drm fd to their main loop and handle other tasks while waiting for the flip to happen. The event includes the time of the flip, the frame counter and a 64 bit opaque token provided by user space in the ioctl. Based on work and suggestions from Jesse Barnes jbar...@virtuousgeek.org, Jakob Bornecrantz wallbra...@gmail.com, Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Kristian Høgsberg k...@redhat.com Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- Ok, another version of this patch. This one has fixes to work with radeon kms plus a missing list head init that would cause an oops in the case where we schedule a flip before the previous one has been queued. I'm now ready to propose this patch for the 2.6.32 merge window. Kristian drivers/gpu/drm/drm_crtc.c | 170 ++- drivers/gpu/drm/drm_crtc_helper.c | 12 ++ drivers/gpu/drm/drm_drv.c |1 + drivers/gpu/drm/drm_fops.c | 68 - drivers/gpu/drm/drm_irq.c | 43 drivers/gpu/drm/i915/i915_drv.c |1 + drivers/gpu/drm/i915/intel_display.c| 24 +++-- drivers/gpu/drm/radeon/radeon_display.c |3 +- include/drm/drm.h | 25 + include/drm/drmP.h | 32 ++ include/drm/drm_crtc.h | 27 + include/drm/drm_crtc_helper.h |4 + include/drm/drm_mode.h | 16 +++ 13 files changed, 414 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8fab789..0906cb3 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -34,6 +34,8 @@ #include drmP.h #include drm_crtc.h +#undef set_base + struct drm_prop_enum_list { int type; char *name; @@ -342,6 +344,34 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb) EXPORT_SYMBOL(drm_framebuffer_cleanup); /** + * drm_crtc_async_flip - do a set_base call from a work queue + * @work: work struct + * + * Called when a set_base call is queued by the page flip code. This + * allows the flip ioctl itself to return immediately and allow userspace + * to continue working. + */ +static void drm_crtc_async_flip(struct work_struct *work) +{ + struct drm_crtc *crtc = container_of(work, struct drm_crtc, async_flip); + struct drm_device *dev = crtc-dev; + struct drm_pending_flip *pending; + + BUG_ON(crtc-pending_flip == NULL); + + mutex_lock(dev-struct_mutex); + crtc-funcs-set_base(crtc, crtc-x, crtc-y, NULL); + + pending = crtc-pending_flip; + crtc-pending_flip = NULL; + + pending-frame = drm_vblank_count(dev, crtc-pipe); + list_add_tail(pending-link, dev-flip_list); + + mutex_unlock(dev-struct_mutex); +} + +/** * drm_crtc_init - Initialise a new CRTC object * @dev: DRM device * @crtc: CRTC object to init @@ -352,17 +382,19 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup); * * Inits a new object created as base part of an driver crtc object. */ -void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, +void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, int pipe, const struct drm_crtc_funcs *funcs) { crtc-dev = dev; crtc-funcs = funcs; + crtc-pipe = pipe; mutex_lock(dev-mode_config.mutex); drm_mode_object_get(dev, crtc-base, DRM_MODE_OBJECT_CRTC); list_add_tail(crtc-head, dev-mode_config.crtc_list); dev-mode_config.num_crtc++; + INIT_WORK(crtc-async_flip, drm_crtc_async_flip); mutex_unlock(dev-mode_config.mutex); } EXPORT_SYMBOL(drm_crtc_init); @@ -381,6 +413,9 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) { struct drm_device *dev = crtc-dev; + mutex_lock(dev-mode_config.mutex); + flush_work(crtc-async_flip); + if (crtc-gamma_store) { kfree(crtc-gamma_store); crtc-gamma_store = NULL; @@ -388,6 +423,7 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) drm_mode_object_put(dev, crtc-base); list_del(crtc-head); + mutex_unlock(dev-mode_config.mutex); dev-mode_config.num_crtc--; } EXPORT_SYMBOL(drm_crtc_cleanup); @@ -2452,3 +2488,135 @@ out: mutex_unlock(dev-mode_config.mutex); return ret; } + +/** + * drm_mode_page_flip_ioctl - page flip ioctl + * @dev: DRM device + * @data
[PATCH] Add modesetting pageflip ioctl and corresponding drm event
This patch adds a vblank synced pageflip ioctl for to the modesetting family of ioctls. The ioctl takes a crtc and an fb and schedules a pageflip to the new fb at the next coming vertical blank event. This feature lets userspace implement tear-free updating of the screen contents with hw-guaranteed low latency page flipping. The ioctl is asynchronous in that it returns immediately and then later notifies the client by making an event available for reading on the drm fd. This lets applications add the drm fd to their main loop and handle other tasks while waiting for the flip to happen. The event includes the time of the flip, the frame counter and a 64 bit opaque token provided by user space in the ioctl. Based on work and suggestions from Jesse Barnes jbar...@virtuousgeek.org, Jakob Bornecrantz wallbra...@gmail.com, Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Kristian Høgsberg k...@redhat.com Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- Ok, another version of this patch. This one has fixes to work with radeon kms plus a missing list head init that would cause an oops in the case where we schedule a flip before the previous one has been queued. I'm now ready to propose this patch for the 2.6.32 merge window. Kristian drivers/gpu/drm/drm_crtc.c | 170 ++- drivers/gpu/drm/drm_crtc_helper.c | 12 ++ drivers/gpu/drm/drm_drv.c |1 + drivers/gpu/drm/drm_fops.c | 68 - drivers/gpu/drm/drm_irq.c | 43 drivers/gpu/drm/i915/i915_drv.c |1 + drivers/gpu/drm/i915/intel_display.c| 24 +++-- drivers/gpu/drm/radeon/radeon_display.c |3 +- include/drm/drm.h | 25 + include/drm/drmP.h | 32 ++ include/drm/drm_crtc.h | 27 + include/drm/drm_crtc_helper.h |4 + include/drm/drm_mode.h | 16 +++ 13 files changed, 414 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8fab789..0906cb3 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -34,6 +34,8 @@ #include drmP.h #include drm_crtc.h +#undef set_base + struct drm_prop_enum_list { int type; char *name; @@ -342,6 +344,34 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb) EXPORT_SYMBOL(drm_framebuffer_cleanup); /** + * drm_crtc_async_flip - do a set_base call from a work queue + * @work: work struct + * + * Called when a set_base call is queued by the page flip code. This + * allows the flip ioctl itself to return immediately and allow userspace + * to continue working. + */ +static void drm_crtc_async_flip(struct work_struct *work) +{ + struct drm_crtc *crtc = container_of(work, struct drm_crtc, async_flip); + struct drm_device *dev = crtc-dev; + struct drm_pending_flip *pending; + + BUG_ON(crtc-pending_flip == NULL); + + mutex_lock(dev-struct_mutex); + crtc-funcs-set_base(crtc, crtc-x, crtc-y, NULL); + + pending = crtc-pending_flip; + crtc-pending_flip = NULL; + + pending-frame = drm_vblank_count(dev, crtc-pipe); + list_add_tail(pending-link, dev-flip_list); + + mutex_unlock(dev-struct_mutex); +} + +/** * drm_crtc_init - Initialise a new CRTC object * @dev: DRM device * @crtc: CRTC object to init @@ -352,17 +382,19 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup); * * Inits a new object created as base part of an driver crtc object. */ -void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, +void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, int pipe, const struct drm_crtc_funcs *funcs) { crtc-dev = dev; crtc-funcs = funcs; + crtc-pipe = pipe; mutex_lock(dev-mode_config.mutex); drm_mode_object_get(dev, crtc-base, DRM_MODE_OBJECT_CRTC); list_add_tail(crtc-head, dev-mode_config.crtc_list); dev-mode_config.num_crtc++; + INIT_WORK(crtc-async_flip, drm_crtc_async_flip); mutex_unlock(dev-mode_config.mutex); } EXPORT_SYMBOL(drm_crtc_init); @@ -381,6 +413,9 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) { struct drm_device *dev = crtc-dev; + mutex_lock(dev-mode_config.mutex); + flush_work(crtc-async_flip); + if (crtc-gamma_store) { kfree(crtc-gamma_store); crtc-gamma_store = NULL; @@ -388,6 +423,7 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) drm_mode_object_put(dev, crtc-base); list_del(crtc-head); + mutex_unlock(dev-mode_config.mutex); dev-mode_config.num_crtc--; } EXPORT_SYMBOL(drm_crtc_cleanup); @@ -2452,3 +2488,135 @@ out: mutex_unlock(dev-mode_config.mutex); return ret; } + +/** + * drm_mode_page_flip_ioctl - page flip ioctl + * @dev: DRM device + * @data
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
2009/8/17 Thomas Hellström tho...@shipmail.org: Kristian Høgsberg wrote: This patch adds a vblank synced pageflip ioctl for to the modesetting family of ioctls. The ioctl takes a crtc and an fb and schedules a pageflip to the new fb at the next coming vertical blank event. This feature lets userspace implement tear-free updating of the screen contents with hw-guaranteed low latency page flipping. The ioctl is asynchronous in that it returns immediately and then later notifies the client by making an event available for reading on the drm fd. This lets applications add the drm fd to their main loop and handle other tasks while waiting for the flip to happen. The event includes the time of the flip, the frame counter and a 64 bit opaque token provided by user space in the ioctl. Based on work and suggestions from Jesse Barnes jbar...@virtuousgeek.org, Jakob Bornecrantz wallbra...@gmail.com, Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Kristian Høgsberg k...@redhat.com Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- Ok, another version of this patch. This one has fixes to work with radeon kms plus a missing list head init that would cause an oops in the case where we schedule a flip before the previous one has been queued. I'm now ready to propose this patch for the 2.6.32 merge window. Hi! First a general question: There is some hardware (for example Unichromes and Chrome9) that can schedule page-flips in the command stream after optional vblank barriers. For this kind of hardware the pageflip would be a matter of scheduling the flip and fence the old and new buffers. No need for delayed unpins and explicit user-space notifications, although the workqueue could be handy to avoid command processing stalls in the vblank barriers. How would such a scheme fit into the framework below? By sending an event back on the file descriptor we allow users of the API to wait on the flip to finish in a standard poll or select mainloop, where it can handle input from other sources while waiting. If you rely on fences, the application will block when it tries to access the buffers protected by the fence, and is unable to handle input from other sources while it's blocking. Even with the vsync barrier in the command stream (which intel hw also supports) you do need to keep the current front buffer pinned for the remainder of the frame, and then you need notification when the swap has happened so that you can unpin the old buffer. I'm sure Unichrome has a command to send an interrupt, which can be queued after the vsync barrier to run the workqueue and trigger this cleanup as well as sending the userspace notification. Kristian drivers/gpu/drm/drm_crtc.c | 170 ++- drivers/gpu/drm/drm_crtc_helper.c | 12 ++ drivers/gpu/drm/drm_drv.c | 1 + drivers/gpu/drm/drm_fops.c | 68 - drivers/gpu/drm/drm_irq.c | 43 drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/intel_display.c | 24 +++-- drivers/gpu/drm/radeon/radeon_display.c | 3 +- include/drm/drm.h | 25 + include/drm/drmP.h | 32 ++ include/drm/drm_crtc.h | 27 + include/drm/drm_crtc_helper.h | 4 + include/drm/drm_mode.h | 16 +++ 13 files changed, 414 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8fab789..0906cb3 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -34,6 +34,8 @@ #include drmP.h #include drm_crtc.h +#undef set_base + struct drm_prop_enum_list { int type; char *name; @@ -342,6 +344,34 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb) EXPORT_SYMBOL(drm_framebuffer_cleanup); /** + * drm_crtc_async_flip - do a set_base call from a work queue + * @work: work struct + * + * Called when a set_base call is queued by the page flip code. This + * allows the flip ioctl itself to return immediately and allow userspace + * to continue working. + */ +static void drm_crtc_async_flip(struct work_struct *work) +{ + struct drm_crtc *crtc = container_of(work, struct drm_crtc, async_flip); + struct drm_device *dev = crtc-dev; + struct drm_pending_flip *pending; + + BUG_ON(crtc-pending_flip == NULL); + + mutex_lock(dev-struct_mutex); Here the struct mutex is taken before a call to a function that doesn't even have dev as an argument. It's a work queue callback, there's no way we can change that to include a dev argument :) Exactly what in the generic modesetting code is protected by the struct mutex here? I'm a little fuzzy on the details, this part of the patch was carried over from Jesse's original work. I believe set_base is supposed to be called
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Mon, Aug 17, 2009 at 4:36 PM, Jesse Barnesjbar...@virtuousgeek.org wrote: On Mon, 17 Aug 2009 22:22:34 +0200 Thomas Hellström tho...@shipmail.org wrote: Kristian Høgsberg wrote: This patch adds a vblank synced pageflip ioctl for to the modesetting family of ioctls. The ioctl takes a crtc and an fb and schedules a pageflip to the new fb at the next coming vertical blank event. This feature lets userspace implement tear-free updating of the screen contents with hw-guaranteed low latency page flipping. The ioctl is asynchronous in that it returns immediately and then later notifies the client by making an event available for reading on the drm fd. This lets applications add the drm fd to their main loop and handle other tasks while waiting for the flip to happen. The event includes the time of the flip, the frame counter and a 64 bit opaque token provided by user space in the ioctl. Based on work and suggestions from Jesse Barnes jbar...@virtuousgeek.org, Jakob Bornecrantz wallbra...@gmail.com, Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Kristian Høgsberg k...@redhat.com Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org --- Ok, another version of this patch. This one has fixes to work with radeon kms plus a missing list head init that would cause an oops in the case where we schedule a flip before the previous one has been queued. I'm now ready to propose this patch for the 2.6.32 merge window. Hi! First a general question: There is some hardware (for example Unichromes and Chrome9) that can schedule page-flips in the command stream after optional vblank barriers. For this kind of hardware the pageflip would be a matter of scheduling the flip and fence the old and new buffers. No need for delayed unpins and explicit user-space notifications, although the workqueue could be handy to avoid command processing stalls in the vblank barriers. How would such a scheme fit into the framework below? If you fence the flip, doesn't that mean you only unpin after it's completed? The initial version of this patch used a command stream flip, but I still had to worry about pinning... If you don't need the userspace notifications we could probably factor that out; do you see any issues with the flip ioctl itself? If not, we can change things as needed if/when more drivers support it... We need the async notiifcation for AIGLX. We can't just block the X server on the flip finishing, we need to be able to suspend and resume the AIGLX client. A couple of years ago, any attempt to return anything else than 0 from drm poll resulted in an X server error. http://freedesktop.org/bugzilla/show_bug.cgi?id=1505. The fix mentioned in the bug was actually to return 0 from drm poll, and a comment about this is still present in drm.git. The above breaks drm for old X servers and all drivers, which I think is against drm policy? Ouch... I remember Kristian had some issues with this part, but I don't think this was one of them. The trouble I ran into here is that the WakeupHandler call chain is called even if select returns with an error, specifically ERESTART when the input SIGIO fires. When that happens the select read fd_set hasn't been changed, which means the drm fd looks readable. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Mon, Aug 17, 2009 at 7:14 PM, Dave Airlieairl...@gmail.com wrote: A couple of years ago, any attempt to return anything else than 0 from drm poll resulted in an X server error. http://freedesktop.org/bugzilla/show_bug.cgi?id=1505. The fix mentioned in the bug was actually to return 0 from drm poll, and a comment about this is still present in drm.git. The above breaks drm for old X servers and all drivers, which I think is against drm policy? That can't be the real problem. The X server polls on a ton of file descriptors already; sockets from clients, dbus, input devices. They all have poll implementations that don't return 0... I mean, otherwise they wouldn't work. Look at evdev_poll() in drivers/input/evdev.c for the evdev poll implementation, for example. Its a very real problem otherwise we wouldn't have a bug open and an bodge around in the kernel to workaround the broken X servers. I didn't say that it wasn't a real problem. I just very seriously doubt that it's because the drm fd now has a poll implementation. There is no difference between, say the evdev fops poll implementation and what I've done in the patch. Also, note that the return value from the poll fops function is not what gets returned from the select(2) syscall. There is no way the poll implementation above can make select(2) return EINVAL that wasn't already possible. Since this stuff is reliant on kms perhaps just use an alternate poll for kms drivers that does it right. I don't know what it is you feel that the implementation in the patch doesn't do right. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: drm sysfs questions
2009/8/13 Thomas Hellström tho...@shipmail.org: Kristian Høgsberg wrote: 2009/8/11 Thomas Hellström tho...@shipmail.org: Jesse Barnes wrote: On Tue, 11 Aug 2009 11:23:09 +0200 Thomas Hellström tho...@shipmail.org wrote: Hi! I'm wondering why we are using a struct device as a sysfs representation for connectors instead of a struct kobject? In particular, what stops the drm_sysfs_[suspend|resume] functions to get called for the connectors, having them cast to a struct drm_minor and sending the cpu to the bushes? Hm, maybe we're just getting lucky that the drm minor check fails for everything but the DRM core device. Yes, I think that's actually the case. kobjects might make sense to move to, unless we can think of other things we'd like to do with a full device (e.g. runtime power management or some sort of per-connector suspend/resume). I can't really think of a case where the device owning the connector can't handle this? But we'd lose the /sys/drm/xxx symlinks to the connectors, and if that does matter, we'd need to recreate those manually. Anyway, I'd also like to be able to add a virtual ttm device to the drm sysfs hierarchy, the purpose of which would be to do the right thing with uncached / write-combined pages at suspend. The virtual device won't be wrapped in a drm minor so I'm wondering wether we could wrap the struct device like so: struct drm_sysfs_device { enum drm_sysfs_device_type type; struct device kdev; } This way the drm sysfs suspend / resume hooks can check the type of the structure embedding the struct device and only call the driver hooks for the relevand device types. There is already a struct device_type mechanism for different types of devices under a subsystem. I'm pretty sure that would be the rigth thing to use, also for the connector devices. The device_type methods are called in addition to the class methods. This means we either have to a) stop the class methods from doing anything or have them distinguish between device types like in the patch I just posted. So if we ditch the class suspend / resume and instead set up a struct device_type for the minor devices to execute the suspend / resume hooks we'd be fine. I can respin the patch to do that. Yup, I think that's a great approach. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: drm sysfs questions
2009/8/11 Thomas Hellström tho...@shipmail.org: Jesse Barnes wrote: On Tue, 11 Aug 2009 11:23:09 +0200 Thomas Hellström tho...@shipmail.org wrote: Hi! I'm wondering why we are using a struct device as a sysfs representation for connectors instead of a struct kobject? In particular, what stops the drm_sysfs_[suspend|resume] functions to get called for the connectors, having them cast to a struct drm_minor and sending the cpu to the bushes? Hm, maybe we're just getting lucky that the drm minor check fails for everything but the DRM core device. Yes, I think that's actually the case. kobjects might make sense to move to, unless we can think of other things we'd like to do with a full device (e.g. runtime power management or some sort of per-connector suspend/resume). I can't really think of a case where the device owning the connector can't handle this? But we'd lose the /sys/drm/xxx symlinks to the connectors, and if that does matter, we'd need to recreate those manually. Anyway, I'd also like to be able to add a virtual ttm device to the drm sysfs hierarchy, the purpose of which would be to do the right thing with uncached / write-combined pages at suspend. The virtual device won't be wrapped in a drm minor so I'm wondering wether we could wrap the struct device like so: struct drm_sysfs_device { enum drm_sysfs_device_type type; struct device kdev; } This way the drm sysfs suspend / resume hooks can check the type of the structure embedding the struct device and only call the driver hooks for the relevand device types. There is already a struct device_type mechanism for different types of devices under a subsystem. I'm pretty sure that would be the rigth thing to use, also for the connector devices. If we make those different device_types, we can keep the connectors as devices. This is useful in connection with libudev, since we can attach properties to specific outputs this way. Like which seat they belong to etc. cheers, Kristian -- Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] Add modesetting pageflip ioctl and corresponding drm event
From: Kristian Høgsberg k...@hinata.local This patch adds a vblank synced pageflip ioctl for to the modesetting family of ioctls. The ioctl takes a crtc and an fb and schedules a pageflip to the new fb at the next coming vertical blank event. This feature lets userspace implement tear-free updating of the screen contents with hw-guaranteed low latency page flipping. The ioctl is asynchronous in that it returns immediately and then later notifies the client by making an event available for reading on the drm fd. This lets applications add the drm fd to their main loop and handle other tasks while waiting for the flip to happen. The event includes the time of the flip, the frame counter and a 64 bit opaque token provided by user space in the ioctl. Based on work and suggestions from Jesse Barnes jbar...@virtuousgeek.org, Jakob Bornecrantz wallbra...@gmail.com, Chris Wilson ch...@chris-wilson.co.uk Signed-off-by: Kristian Høgsberg k...@redhat.com --- Ok, here's the latest roll-up of the page flipping patch with the fixes from Jesse and Chris. drivers/gpu/drm/drm_crtc.c | 169 +- drivers/gpu/drm/drm_crtc_helper.c|8 +- drivers/gpu/drm/drm_drv.c|1 + drivers/gpu/drm/drm_fops.c | 68 +- drivers/gpu/drm/drm_irq.c| 43 + drivers/gpu/drm/i915/i915_drv.c |1 + drivers/gpu/drm/i915/intel_display.c | 25 +++-- include/drm/drm.h| 25 + include/drm/drmP.h | 32 +++ include/drm/drm_crtc.h | 27 ++ include/drm/drm_crtc_helper.h|4 - include/drm/drm_mode.h | 16 +++ 12 files changed, 400 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8fab789..32212e6 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -34,6 +34,8 @@ #include drmP.h #include drm_crtc.h +#undef set_base + struct drm_prop_enum_list { int type; char *name; @@ -342,6 +344,34 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb) EXPORT_SYMBOL(drm_framebuffer_cleanup); /** + * drm_crtc_async_flip - do a set_base call from a work queue + * @work: work struct + * + * Called when a set_base call is queued by the page flip code. This + * allows the flip ioctl itself to return immediately and allow userspace + * to continue working. + */ +static void drm_crtc_async_flip(struct work_struct *work) +{ + struct drm_crtc *crtc = container_of(work, struct drm_crtc, async_flip); + struct drm_device *dev = crtc-dev; + struct drm_pending_flip *pending; + + BUG_ON(crtc-pending_flip == NULL); + + mutex_lock(dev-struct_mutex); + crtc-funcs-set_base(crtc, 0, 0, NULL); + + pending = crtc-pending_flip; + crtc-pending_flip = NULL; + + pending-frame = drm_vblank_count(dev, crtc-pipe); + list_add_tail(pending-link, dev-flip_list); + + mutex_unlock(dev-struct_mutex); +} + +/** * drm_crtc_init - Initialise a new CRTC object * @dev: DRM device * @crtc: CRTC object to init @@ -352,17 +382,19 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup); * * Inits a new object created as base part of an driver crtc object. */ -void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, +void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, int pipe, const struct drm_crtc_funcs *funcs) { crtc-dev = dev; crtc-funcs = funcs; + crtc-pipe = pipe; mutex_lock(dev-mode_config.mutex); drm_mode_object_get(dev, crtc-base, DRM_MODE_OBJECT_CRTC); list_add_tail(crtc-head, dev-mode_config.crtc_list); dev-mode_config.num_crtc++; + INIT_WORK(crtc-async_flip, drm_crtc_async_flip); mutex_unlock(dev-mode_config.mutex); } EXPORT_SYMBOL(drm_crtc_init); @@ -381,6 +413,9 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) { struct drm_device *dev = crtc-dev; + mutex_lock(dev-mode_config.mutex); + flush_work(crtc-async_flip); + if (crtc-gamma_store) { kfree(crtc-gamma_store); crtc-gamma_store = NULL; @@ -388,6 +423,7 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) drm_mode_object_put(dev, crtc-base); list_del(crtc-head); + mutex_unlock(dev-mode_config.mutex); dev-mode_config.num_crtc--; } EXPORT_SYMBOL(drm_crtc_cleanup); @@ -2452,3 +2488,134 @@ out: mutex_unlock(dev-mode_config.mutex); return ret; } + +/** + * drm_mode_page_flip_ioctl - page flip ioctl + * @dev: DRM device + * @data: ioctl args + * @file_priv: file private data + * + * The page flip ioctl replaces the current front buffer with a new + * one, using the CRTC's set_base function, which should just update + * the front buffer base pointer. It's up to set_base to make + * sure the update doesn't result
Re: [PATCH] drm: remove root requirement from DRM_IOCTL_SET_VERSION
On Fri, Jul 3, 2009 at 5:47 AM, Daniel Stonedan...@fooishbar.org wrote: On Wed, Jul 01, 2009 at 09:39:17PM -0400, Kristian Høgsberg wrote: If we want to do better (and if we care about security enhanced X in a [... snipped for brevity ...] session server is a client of a system display server. Which is why ... ? :) Yes, sorry, that got a little long and incoherent. I blame sleep deprivation :) There's a couple of valid points in there, though: 1) Yes, let's remove root requirement from DRM_IOCTL_AUTH_MAGIC. 2) DRM authentication is compromised by the dropMaster/setMaster ioctls used to support DRI capable X servers on multiple VTs. Authentication is a global flag on the filp, and isn't restricted to the resources provided by the authenticating master (X server). So a DRI client from one server can now get at the front buffer from another server. The rest of the mail is rambling about whether we care about this and if so ideas for solving it. The XACE work is trying harden the protocol to prevent clients from writing to the root window, reading out pixels from other windows etc. If we're serious about that effort, we need to think about a better authentication scheme since right now drm is a big back door to the protocol from the XACE point of view. Which resources are you authenticating to access, and how do we enforce that? The session / system display server is something I've started thinking about for wayland: in the case where you have several sessions, multi seat, fast user switching, or graphical vt's, native rdp clients, native qemu sessions, you'll want some process in charge of switching between those sessions. I'm calling that a system compositor, and it could be a wayland server... or an X server, I suppose. As a client of the system compositor, you have your GNOME session running in a nested X server or a Moblin session running under a nested wayland server or whatever. At that point you have two simultaneous authentication domains active and clients from the Moblin session should not be able to go peeking into the system compositors buffers. cheers, Kristian -- -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] drm: remove root requirement from DRM_IOCTL_SET_VERSION
On Wed, Jul 1, 2009 at 12:55 PM, Jesse Barnesjbar...@virtuousgeek.org wrote: On Tue, 30 Jun 2009 23:43:19 -0700 Eric Anholt e...@anholt.net wrote: On Mon, 2009-06-29 at 16:52 -0700, Jesse Barnes wrote: Just a DRM_MASTER flag is sufficient here, though maybe this call is totally deprecated anyway (xf86-video-intel still calls it though). Signed-off-by: Jesse Barnes jbar...@virtuousgeek.org Acked-by: Eric Anholt e...@anholt.net We'll also need to do something about DRM_IOCTL_AUTH_MAGIC... is it safe to make that master only? I suppose. The auth concept is pretty fuzzy / watered out at this point, with dri2 and multiple drm masters. If you vt switch away from one X server to a different vt and auth with the X server there, you're equally authenticated with the first server and can access all its buffers if they have global names and you know those names. So making AUTH_MAGIC master only doesn't make it anything less secure, it just means that you can get auth directly instead of going through a setuid X server to get authenticated. Or I guess we could change the implementation to not just remember an auth bit, but also the master it auth'ed with. If we want to do better (and if we care about security enhanced X in a GEM world we do) we need something like an auth group. We'll want to support multiple groups active at the same time (that is, more flexible than the current drop/set master where only one is active at a time) and we'll want to support clients that are members of several groups at the same time. So, an auth group would be an X server and its direct rendering clients (or a wayland server). The server could in turn be a client of another server, for example for a secure nested containerized server under your normal desktop session or maybe your session server is a client of a system display server. Which is why Of course, the sticking point is that if we want to enforce this access control, we need to do it at the GEM level. We need to verify that the client has access to the buffers it uses (in all the ioctls that operate on a global name) and that the batch buffers doesn't contain references to absolute gart addresses that could reference buffer objects the client isn't authenticated to get at. Or just unbind/evict all buffers that client isn't allow to touch when it submits batch buffer. Changing AUTH_MAGIC to not require root doesn't compromise anything more than it currently is. We should probably track the master a file is auth'ed with and not just the file-authenticated bit. I suppose we can add the paranoid secure scheme later, if necessary, as an opt-in. If you want to run a secure X/wayland server, you create an auth group and all the buffers for that server and it's clients belong to that group. Those buffers get evicted when a non-authed client submits an execbuffer. So just make it a no-op, and make it not require root. cheers, Kristian -- -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [Intel-gfx] [PATCH] Add modesetting pageflip ioctl and corresponding drm event
On Tue, Jun 30, 2009 at 2:37 PM, Chris Wilsonch...@chris-wilson.co.uk wrote: I've just got around to playing with the modesetting page-flip ioctl and found a nasty rendering glitch where the flip occurred before the rendering was flushed. This appears to be because the finish of the pending_flip is queued at the same time as the async set_base(). Applying the following patch prevents the glitch for me: Yikes, that's embarassing. I saw the same kind of glitch that when running this with wayland too but never debugged it. Your patch looks good, but I haven't tested it yet. thanks, Kristian From aa017e6056cf2faf6be7eeaa71d2fded4a9f6295 Mon Sep 17 00:00:00 2001 From: Chris Wilson ch...@chris-wilson.co.uk Date: Tue, 30 Jun 2009 18:21:54 +0100 Subject: [PATCH 1/3] drm: delay unpinning the current fb til after the flip is complete --- drivers/gpu/drm/drm_crtc.c | 45 +++ drivers/gpu/drm/drm_irq.c | 7 +++-- include/drm/drm_crtc.h | 4 ++- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6a5a779..32212e6 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -344,20 +344,30 @@ void drm_framebuffer_cleanup(struct drm_framebuffer *fb) EXPORT_SYMBOL(drm_framebuffer_cleanup); /** - * drm_crtc_async_work - do a set_base call from a work queue + * drm_crtc_async_flip - do a set_base call from a work queue * @work: work struct * * Called when a set_base call is queued by the page flip code. This * allows the flip ioctl itself to return immediately and allow userspace * to continue working. */ -static void drm_crtc_async_work(struct work_struct *work) +static void drm_crtc_async_flip(struct work_struct *work) { - struct drm_crtc *crtc = container_of(work, struct drm_crtc, async_work); + struct drm_crtc *crtc = container_of(work, struct drm_crtc, async_flip); struct drm_device *dev = crtc-dev; + struct drm_pending_flip *pending; + + BUG_ON(crtc-pending_flip == NULL); mutex_lock(dev-struct_mutex); crtc-funcs-set_base(crtc, 0, 0, NULL); + + pending = crtc-pending_flip; + crtc-pending_flip = NULL; + + pending-frame = drm_vblank_count(dev, crtc-pipe); + list_add_tail(pending-link, dev-flip_list); + mutex_unlock(dev-struct_mutex); } @@ -384,7 +394,7 @@ void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, int pipe, list_add_tail(crtc-head, dev-mode_config.crtc_list); dev-mode_config.num_crtc++; - INIT_WORK(crtc-async_work, drm_crtc_async_work); + INIT_WORK(crtc-async_flip, drm_crtc_async_flip); mutex_unlock(dev-mode_config.mutex); } EXPORT_SYMBOL(drm_crtc_init); @@ -404,7 +414,7 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) struct drm_device *dev = crtc-dev; mutex_lock(dev-mode_config.mutex); - flush_work(crtc-async_work); + flush_work(crtc-async_flip); if (crtc-gamma_store) { kfree(crtc-gamma_store); @@ -2569,9 +2579,6 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data, goto out_unlock; } - pending-frame = drm_vblank_count(dev, crtc-pipe); - list_add_tail(pending-link, dev-flip_list); - /* * The set_base call will change the domain on the new fb, * which will force the rendering to finish and block the @@ -2580,7 +2587,27 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data, */ crtc-fb = obj_to_fb(fb_obj); - schedule_work(crtc-async_work); + if (crtc-pending_flip != NULL) { + struct drm_pending_flip *old_flip; + + /* We have an outstanding flip request for this crtc/pipe. + * In order to satisfy the user we can either queue the requests + * and apply them on sequential vblanks, or we can drop old + * requests. + * + * Here we choose to discard the previous request for + * simplicity. Note that since we have not yet applied the + * previous flip, we need to preserve the original (i.e. still + * current) fb. + */ + + old_flip = crtc-pending_flip; + pending-old_fb = old_flip-old_fb; + old_flip-old_fb = NULL; + drm_finish_pending_flip (dev, old_flip, 0); + } else + schedule_work(crtc-async_flip); + crtc-pending_flip = pending; mutex_unlock(dev-struct_mutex); diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 8b4d0c8..c7a17f6 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -72,7 +72,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, return 0; } -#define vblank_after(a,b) ((long)(b) - (long)(a) 0)
Re: GLX makeCurrent in glean vs broken X server glxAllContexts linked list
On Wed, 2009-06-10 at 15:20 +1000, Dave Airlie wrote: Hi Kristian et al So you wrote YALL for glxAllContexts and like all good linked list re-implementations it didn't work :-) Well that's how we do data structures in the X server, open coded and badly. So the attached patch fixes the linked list remove function, so we do clean up the drawable and context properly. However now I'm getting a glean failure on the makeCurrent test [airl...@pegasus piglit]$ ./bin/glean -o -r dave -t makeCurrent makeCurrent: PASS rgba8, db, z24, s8, win+pmap, id 33 X Error of failed request: GLXBadCurrentWindow Major opcode of failed request: 152 (GLX) Minor opcode of failed request: 5 (X_GLXMakeCurrent) Serial number of failed request: 103 Current serial number in output stream: 103 this is better than what I was getting before I fixed it which was my X server crashing. However I'm just wondering if anyone knows what the proper behaviour is here, glean test needs fixing? or our GLX implementation needs fixing? The patch is definitely a step in the right direction, but I suspect glean is right though and that something else is wrong in the glx code. I'll try to take a look. cheers, Kristian -- Crystal Reports - New Free Runtime and 30 Day Trial Check out the new simplified licensing option that enables unlimited royalty-free distribution of the report engine for externally facing server and web deployment. http://p.sf.net/sfu/businessobjects -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] Add modesetting pageflip ioctl and corresponding drm event
From: Kristian Høgsberg k...@redhat.com This patch adds a vblank synced pageflip ioctl for to the modesetting family of ioctls. The ioctl takes a crtc and an fb and schedules a pageflip to the new fb at the next coming vertical blank event. This feature lets userspace implement tear-free updating of the screen contents with hw-guaranteed low latency page flipping. The ioctl is asynchronous in that it returns immediately and then later notifies the client by making an event available for reading on the drm fd. This lets applications add the drm fd to their main loop and handle other tasks while waiting for the flip to happen. The event includes the time of the flip, the frame counter and a 64 bit opaque token provided by user space in the ioctl. Based on initial work and suggestions from Jesse Barnes jbar...@virtuousgeek.org and Jakob Bornecrantz wallbra...@gmail.com. Signed-off-by: Kristian Høgsberg k...@redhat.com --- This update addresses a few of the issues brought up by Jakob: - the u64 user_data field is moved the page flip event from the drm header struct. - the implementation of the page flip ioctl is moved to drm_crtc.h instead of drm_crtc_helper.c and cleanup in drm_release() is simpler and should clean up everything (it was missing an unpin before, now we just use the same code as the normal drm_read() case). What's still missing is: - don't block on setting the domain in set_base - the synchronous version of the ioctl; userspace can just use the ioctl followed by a read loop. I'll be updating userspace, but I'm moving slowly on this - I can't get to that before next week. Fedora 11 blockers and all... cheers, Kristian drivers/gpu/drm/drm_crtc.c | 120 +- drivers/gpu/drm/drm_crtc_helper.c| 14 +++-- drivers/gpu/drm/drm_drv.c|1 + drivers/gpu/drm/drm_fops.c | 68 +++- drivers/gpu/drm/drm_irq.c| 42 drivers/gpu/drm/i915/i915_drv.c |1 + drivers/gpu/drm/i915/intel_display.c | 27 +--- include/drm/drm.h| 25 +++ include/drm/drmP.h | 32 + include/drm/drm_crtc.h | 21 ++ include/drm/drm_crtc_helper.h|4 - include/drm/drm_mode.h | 16 + 12 files changed, 348 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 94a7688..5f63ca0 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -352,11 +352,12 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup); * * Inits a new object created as base part of an driver crtc object. */ -void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, +void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, int pipe, const struct drm_crtc_funcs *funcs) { crtc-dev = dev; crtc-funcs = funcs; + crtc-pipe = pipe; mutex_lock(dev-mode_config.mutex); drm_mode_object_get(dev, crtc-base, DRM_MODE_OBJECT_CRTC); @@ -2447,3 +2448,120 @@ out: mutex_unlock(dev-mode_config.mutex); return ret; } + +/** + * drm_mode_page_flip_ioctl - page flip ioctl + * @dev: DRM device + * @data: ioctl args + * @file_priv: file private data + * + * The page flip ioctl replaces the current front buffer with a new + * one, using the CRTC's set_base function, which should just update + * the front buffer base pointer. It's up to set_base to make + * sure the update doesn't result in tearing (on some hardware the + * base register is double buffered, so this is easy). + * + * Note that this covers just the simple case of flipping the front + * buffer immediately. Interval handling and interlaced modes have to + * be handled by userspace, or with new ioctls. + */ +int drm_mode_page_flip_ioctl(struct drm_device *dev, void *data, +struct drm_file *file_priv) +{ + struct drm_pending_flip *pending; + struct drm_mode_page_flip *flip_data = data; + struct drm_mode_object *drm_obj, *fb_obj; + struct drm_crtc *crtc; + int ret = 0; + + if (!(drm_core_check_feature(dev, DRIVER_MODESET))) + return -ENODEV; + + /* +* Reject unknown flags so future userspace knows what we (don't) +* support +*/ + if (flip_data-flags (~DRM_MODE_PAGE_FLIP_FLAGS_MASK)) { + DRM_DEBUG(bad page flip flags\n); + return -EINVAL; + } + + pending = kzalloc(sizeof *pending, GFP_KERNEL); + if (pending == NULL) + return -ENOMEM; + + mutex_lock(dev-struct_mutex); + + fb_obj = drm_mode_object_find(dev, flip_data-fb_id, + DRM_MODE_OBJECT_FB); + if (!fb_obj) { + DRM_DEBUG(unknown fb %d\n, flip_data-fb_id
[PATCH] Add modesetting pageflip ioctl and corresponding drm event
From: Kristian Høgsberg k...@redhat.com This patch adds a vblank synced pageflip ioctl for to the modesetting family of ioctls. The ioctl takes a crtc and an fb and schedules a pageflip to the new fb at the next coming vertical blank event. This feature lets userspace implement tear-free updating of the screen contents with hw-guaranteed low latency page flipping. The ioctl is asynchronous in that it returns immediately and then later notifies the client by making an event available for reading on the drm fd. This lets applications add the drm fd to their main loop and handle other tasks while waiting for the flip to happen. The event includes the time of the flip, the frame counter and a 64 bit opaque token provided by user space in the ioctl. Based on initial work and suggestions from Jesse Barnes jbar...@virtuousgeek.org and Jakob Bornecrantz wallbra...@gmail.com. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_crtc.c |3 +- drivers/gpu/drm/drm_crtc_helper.c| 123 ++ drivers/gpu/drm/drm_drv.c|1 + drivers/gpu/drm/drm_fops.c | 72 +++- drivers/gpu/drm/drm_irq.c| 44 drivers/gpu/drm/i915/i915_drv.c |1 + drivers/gpu/drm/i915/intel_display.c | 22 -- include/drm/drm.h| 25 +++ include/drm/drmP.h | 30 include/drm/drm_crtc.h |5 ++ include/drm/drm_crtc_helper.h| 15 - include/drm/drm_mode.h | 16 + 12 files changed, 345 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 94a7688..4c39350 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -352,11 +352,12 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup); * * Inits a new object created as base part of an driver crtc object. */ -void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, +void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, int pipe, const struct drm_crtc_funcs *funcs) { crtc-dev = dev; crtc-funcs = funcs; + crtc-pipe = pipe; mutex_lock(dev-mode_config.mutex); drm_mode_object_get(dev, crtc-base, DRM_MODE_OBJECT_CRTC); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index a04639d..d53417e 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -593,8 +593,10 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, if (drm_mode_equal(saved_mode, crtc-mode)) { if (saved_x != crtc-x || saved_y != crtc-y || depth_changed || bpp_changed) { + mutex_lock(dev-struct_mutex); ret = !crtc_funcs-mode_set_base(crtc, crtc-x, crtc-y, old_fb); + mutex_unlock(dev-struct_mutex); goto done; } } @@ -864,8 +866,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) old_fb = set-crtc-fb; if (set-crtc-fb != set-fb) set-crtc-fb = set-fb; + mutex_lock(dev-struct_mutex); ret = crtc_funcs-mode_set_base(set-crtc, set-x, set-y, old_fb); + mutex_unlock(dev-struct_mutex); if (ret != 0) goto fail_set_mode; } @@ -1007,3 +1011,122 @@ int drm_helper_resume_force_mode(struct drm_device *dev) return 0; } EXPORT_SYMBOL(drm_helper_resume_force_mode); + +/** + * drm_mode_page_flip - page flip ioctl + * @dev: DRM device + * @data: ioctl args + * @file_priv: file private data + * + * The page flip ioctl replaces the current front buffer with a new one, + * using the CRTC's mode_set_base function, which should just update + * the front buffer base pointer. It's up to mode_set_base to make + * sure the update doesn't result in tearing (on some hardware the base + * register is double buffered, so this is easy). + * + * Note that this covers just the simple case of flipping the front + * buffer immediately. Interval handling and interlaced modes have to + * be handled by userspace, or with new ioctls. + */ +int drm_mode_page_flip(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_pending_flip *pending; + struct drm_mode_page_flip *flip_data = data; + struct drm_mode_object *drm_obj, *fb_obj; + struct drm_crtc *crtc; + struct drm_crtc_helper_funcs *crtc_funcs; + int ret = 0; + + if (!(drm_core_check_feature(dev, DRIVER_MODESET))) + return -ENODEV; + + /* +* Reject unknown flags so future userspace knows what we (don't) +* support
[PATCH] Add modesetting pageflip ioctl and corresponding drm event
From: Kristian Høgsberg k...@redhat.com This patch adds a vblank synced pageflip ioctl for to the modesetting family of ioctls. The ioctl takes a crtc and an fb and schedules a pageflip to the new fb at the next coming vertical blank event. This feature lets userspace implement tear-free updating of the screen contents with hw-guaranteed low latency page flipping. The ioctl is asynchronous in that it returns immediately and then later notifies the client by making an event available for reading on the drm fd. This lets applications add the drm fd to their main loop and handle other tasks while waiting for the flip to happen. The event includes the time of the flip, the frame counter and a 64 bit opaque token provided by user space in the ioctl. Based on initial work and suggestions from Jesse Barnes jbar...@virtuousgeek.org and Jakob Bornecrantz wallbra...@gmail.com. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_crtc.c |3 +- drivers/gpu/drm/drm_crtc_helper.c| 123 ++ drivers/gpu/drm/drm_drv.c|1 + drivers/gpu/drm/drm_fops.c | 72 +++- drivers/gpu/drm/drm_irq.c| 44 drivers/gpu/drm/i915/i915_drv.c |1 + drivers/gpu/drm/i915/intel_display.c | 22 -- include/drm/drm.h| 25 +++ include/drm/drmP.h | 30 include/drm/drm_crtc.h |5 ++ include/drm/drm_crtc_helper.h| 15 - include/drm/drm_mode.h | 16 + 12 files changed, 345 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 94a7688..4c39350 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -352,11 +352,12 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup); * * Inits a new object created as base part of an driver crtc object. */ -void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, +void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, int pipe, const struct drm_crtc_funcs *funcs) { crtc-dev = dev; crtc-funcs = funcs; + crtc-pipe = pipe; mutex_lock(dev-mode_config.mutex); drm_mode_object_get(dev, crtc-base, DRM_MODE_OBJECT_CRTC); diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index a04639d..d53417e 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -593,8 +593,10 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, if (drm_mode_equal(saved_mode, crtc-mode)) { if (saved_x != crtc-x || saved_y != crtc-y || depth_changed || bpp_changed) { + mutex_lock(dev-struct_mutex); ret = !crtc_funcs-mode_set_base(crtc, crtc-x, crtc-y, old_fb); + mutex_unlock(dev-struct_mutex); goto done; } } @@ -864,8 +866,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) old_fb = set-crtc-fb; if (set-crtc-fb != set-fb) set-crtc-fb = set-fb; + mutex_lock(dev-struct_mutex); ret = crtc_funcs-mode_set_base(set-crtc, set-x, set-y, old_fb); + mutex_unlock(dev-struct_mutex); if (ret != 0) goto fail_set_mode; } @@ -1007,3 +1011,122 @@ int drm_helper_resume_force_mode(struct drm_device *dev) return 0; } EXPORT_SYMBOL(drm_helper_resume_force_mode); + +/** + * drm_mode_page_flip - page flip ioctl + * @dev: DRM device + * @data: ioctl args + * @file_priv: file private data + * + * The page flip ioctl replaces the current front buffer with a new one, + * using the CRTC's mode_set_base function, which should just update + * the front buffer base pointer. It's up to mode_set_base to make + * sure the update doesn't result in tearing (on some hardware the base + * register is double buffered, so this is easy). + * + * Note that this covers just the simple case of flipping the front + * buffer immediately. Interval handling and interlaced modes have to + * be handled by userspace, or with new ioctls. + */ +int drm_mode_page_flip(struct drm_device *dev, void *data, + struct drm_file *file_priv) +{ + struct drm_pending_flip *pending; + struct drm_mode_page_flip *flip_data = data; + struct drm_mode_object *drm_obj, *fb_obj; + struct drm_crtc *crtc; + struct drm_crtc_helper_funcs *crtc_funcs; + int ret = 0; + + if (!(drm_core_check_feature(dev, DRIVER_MODESET))) + return -ENODEV; + + /* +* Reject unknown flags so future userspace knows what we (don't) +* support
[PATCH] libdrm: add KMS page flip interface
From: Jesse Barnes jbar...@virtuousgeek.org Sits on top of KMS page flipping ioctl. --- Userspace side of the async pageflip ioctl plus a test case added to modetest.c libdrm/xf86drmMode.c | 13 libdrm/xf86drmMode.h |4 +- shared-core/drm.h | 26 - shared-core/drm_mode.h| 16 + tests/modetest/modetest.c | 137 ++-- 5 files changed, 185 insertions(+), 11 deletions(-) diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index ea11207..80ac57d 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -664,3 +664,16 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, return 0; } + +int drmModePageFlip(int fd, uint32_t crtc_id, + uint32_t fb_id, void *user_data) +{ + struct drm_mode_page_flip flip; + + flip.fb_id = fb_id; + flip.crtc_id = crtc_id; + flip.user_data = VOID2U64(user_data); + flip.flags = 0; + + return drmIoctl(fd, DRM_IOCTL_MODE_PAGE_FLIP, flip); +} diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h index 62304bb..730184e 100644 --- a/libdrm/xf86drmMode.h +++ b/libdrm/xf86drmMode.h @@ -259,8 +259,6 @@ typedef struct _drmModeConnector { uint32_t *encoders; /** List of encoder ids */ } drmModeConnector, *drmModeConnectorPtr; - - extern void drmModeFreeModeInfo( drmModeModeInfoPtr ptr ); extern void drmModeFreeResources( drmModeResPtr ptr ); extern void drmModeFreeFB( drmModeFBPtr ptr ); @@ -357,8 +355,8 @@ extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr); extern int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id, uint64_t value); extern int drmCheckModesettingSupported(const char *busid); - extern int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, uint16_t *red, uint16_t *green, uint16_t *blue); extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, uint16_t *red, uint16_t *green, uint16_t *blue); +extern int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, void *user_data); diff --git a/shared-core/drm.h b/shared-core/drm.h index b97ba09..b01fc43 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1107,7 +1107,7 @@ struct drm_gem_open { #define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_RMFBDRM_IOWR(0xAF, uint32_t) -#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xB0, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_PAGE_FLIP DRM_IOW( 0xB0, struct drm_mode_page_flip) /*...@}*/ @@ -1122,6 +1122,30 @@ struct drm_gem_open { #define DRM_COMMAND_BASE0x40 #define DRM_COMMAND_END 0xA0 +/** + * Header for events written back to userspace on the drm fd. The + * type defines the type of event, the length specifies the total + * length of the event (including the header), and user_data is + * typically a 64 bit value passed with the ioctl that triggered the + * event. A read on the drm fd will always only return complete + * events, that is, if for example the read buffer is 100 bytes, and + * there are two 64 byte events pending, only one will be returned. + */ +struct drm_event { + uint32_t type; + uint32_t length; + uint64_t user_data; +}; + +#define DRM_EVENT_MODE_PAGE_FLIP 0x01 + +struct drm_event_page_flip { + struct drm_event base; + uint32_t tv_sec; + uint32_t tv_usec; + uint32_t frame; +}; + /* typedef area */ #ifndef __KERNEL__ typedef struct drm_clip_rect drm_clip_rect_t; diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h index 9b92733..bebe4e7 100644 --- a/shared-core/drm_mode.h +++ b/shared-core/drm_mode.h @@ -270,4 +270,20 @@ struct drm_mode_crtc_lut { uint64_t blue; }; +#define DRM_MODE_PAGE_FLIP_WAIT(10) /* block on previous page flip */ +#define DRM_MODE_PAGE_FLIP_FLAGS_MASK (DRM_MODE_PAGE_FLIP_WAIT) + +struct drm_mode_page_flip { + /** Handle of new front buffer */ + uint32_t fb_id; + uint32_t crtc_id; + + /* 64 bit cookie returned to userspace in the page flip event. */ + uint64_t user_data; + /** +* page flip flags (wait on flip only for now) +*/ + uint32_t flags; +}; + #endif diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 58e0e4c..6eed564 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -46,6 +46,7 @@ #include unistd.h #include string.h #include errno.h +#include sys/poll.h #include xf86drm.h #include xf86drmMode.h @@ -271,6 +272,9 @@ struct connector { drmModeModeInfo *mode; drmModeEncoder *encoder; int crtc; + unsigned int fb_id; + struct timeval start; +
Re: [Intel-gfx] [RFC] DRI2 swapbuffers (yes yet again)
2009/5/5 Ian Romanick i...@freedesktop.org: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Kristian Høgsberg wrote: On Tue, May 5, 2009 at 12:20 PM, Jesse Barnes jbar...@virtuousgeek.org wrote: On Mon, 04 May 2009 19:14:29 -0700 Ian Romanick i...@freedesktop.org wrote: Having this ability would allow us to advertise some fbconfigs with GLX_SWAP_METHOD_OML = GLX_SWAP_COPY_OML. We obviously don't have any apps that use that today, but I can think of a couple that should. :) Yeah, ok. It's not something that needs to be exposed in the protocol or dri2 module. If you want the copy behaviour, use DRI2CopyRegion(). Another point about GLX_SWAP_METHOD_OML is that we can't really implement the always swap (GLX_SWAP_EXCHANGE_OML) behaviour without a fair bit of yucky code, and without that we can't really claim to support the extension. I think you misunderstand the extension. The fbconfig has an extra value that says this is how glXSwapBuffer happens. The three possible values are: flip, copy, unknown. Right now we support this extension, but we always say unknown. As you point out, I doubt we'd ever be able to say flip, but we might be able to say copy and unknown. Telling the application flip isn't terribly useful, but a lot of applications could do something smart (i.e., partial screen updates) if they knew the swap method was always copy. Right? Ah, yes, that works. I was thinking that it was a drawable attribute you could specify at glx drawable creation time, but if it's a config attribute, we can just expose the ones we support. Cool. Kristian -- The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your production scanning environment may not be a perfect world - but thanks to Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700 Series Scanner you'll get full speed at 300 dpi even with all image processing features enabled. http://p.sf.net/sfu/kodak-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [Intel-gfx] [RFC] DRI2 swapbuffers (yes yet again)
On Tue, May 5, 2009 at 2:34 PM, Jesse Barnes jbar...@virtuousgeek.org wrote: On Tue, 05 May 2009 11:24:29 -0700 Ian Romanick i...@freedesktop.org wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Kristian Høgsberg wrote: On Tue, May 5, 2009 at 12:20 PM, Jesse Barnes jbar...@virtuousgeek.org wrote: On Mon, 04 May 2009 19:14:29 -0700 Ian Romanick i...@freedesktop.org wrote: Having this ability would allow us to advertise some fbconfigs with GLX_SWAP_METHOD_OML = GLX_SWAP_COPY_OML. We obviously don't have any apps that use that today, but I can think of a couple that should. :) Yeah, ok. It's not something that needs to be exposed in the protocol or dri2 module. If you want the copy behaviour, use DRI2CopyRegion(). Another point about GLX_SWAP_METHOD_OML is that we can't really implement the always swap (GLX_SWAP_EXCHANGE_OML) behaviour without a fair bit of yucky code, and without that we can't really claim to support the extension. I think you misunderstand the extension. The fbconfig has an extra value that says this is how glXSwapBuffer happens. The three possible values are: flip, copy, unknown. Right now we support this extension, but we always say unknown. As you point out, I doubt we'd ever be able to say flip, but we might be able to say copy and unknown. Telling the application flip isn't terribly useful, but a lot of applications could do something smart (i.e., partial screen updates) if they knew the swap method was always copy. Right? Actually I think we could do flip as well, depending on the expected semantics. If all apps had fake front buffers (i.e. private back *and* front buffers), we could simply exchange those two at swapbuffers time. That assumes a reasonably intelligent compositing manager though; we wouldn't want to immediately follow any swap by a copy to the real front buffer or there'd be no benefit. However if the compositing manager was responsible for copying all the fake fronts to the real front if swaps had occurred it could be a win in terms of consumed bandwidth and swap latency (I think Wayland does it this way?). I wayland page flipping/copying, double, triple or n-buffering is all client side decisions. Wayland only knows about the front buffer (which doesn't have child windows or other cliprects), all the other buffers are managed by the client. The client can do page flipping by passing attaching a new buffer handle to the surface or copy (all or regions) from a temp/back buffer to the wayland surface. How many buffers to keep around and whether or when to block rendering is up to the client. On X, we unfortunately always have to do the copy to the front buffer, though we could probably get smarter about the frequency. The main reason we can't easily promise flipping under X is child windows and clip-rects. We could fake it by copying back the dirty regions from the new front to the back just after the flip, at that point it's not really worthwhile anymore, and definitely too complex. cheers, Kristian -- The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your production scanning environment may not be a perfect world - but thanks to Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700 Series Scanner you'll get full speed at 300 dpi even with all image processing features enabled. http://p.sf.net/sfu/kodak-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [Intel-gfx] [RFC] DRI2 swapbuffers (yes yet again)
On Tue, May 5, 2009 at 12:20 PM, Jesse Barnes jbar...@virtuousgeek.org wrote: On Mon, 04 May 2009 19:14:29 -0700 Ian Romanick i...@freedesktop.org wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Jesse Barnes wrote: On Mon, 04 May 2009 14:45:07 -0700 Ian Romanick i...@freedesktop.org wrote: There's a problem in dri2SwapBuffers. If a new libGL is used with an old driver, psc-dri2-setBuffers won't be set, right? Yes. I should probably add an #ifdef for that like -flush has. No, I mean what happens you if you build a driver from, say, mesa_7_4_branch and use it with libGL that has your patches applied. The compile-time check won't cut it. Oh runtime mixing too... is that common? Also, should there be a mechanism for the 3D driver to force swap buffers to be implemented with a copy? Hm, well the 2D driver can easily force it by not implementing a swapbuffers function or by returning NULL, but I guess allowing the 3D driver to force it would be ok to. Could probably just check for -setbuffers? Or maybe add a way for the driver to set the swapAvailable flag... Having this ability would allow us to advertise some fbconfigs with GLX_SWAP_METHOD_OML = GLX_SWAP_COPY_OML. We obviously don't have any apps that use that today, but I can think of a couple that should. :) Yeah, ok. It's not something that needs to be exposed in the protocol or dri2 module. If you want the copy behaviour, use DRI2CopyRegion(). Another point about GLX_SWAP_METHOD_OML is that we can't really implement the always swap (GLX_SWAP_EXCHANGE_OML) behaviour without a fair bit of yucky code, and without that we can't really claim to support the extension. cheers, Kristian -- The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your production scanning environment may not be a perfect world - but thanks to Kodak, there's a perfect scanner to get the job done! With the NEW KODAK i700 Series Scanner you'll get full speed at 300 dpi even with all image processing features enabled. http://p.sf.net/sfu/kodak-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: generic libdrm memory manager
On Thu, Apr 23, 2009 at 7:23 AM, Abraham Varricatt abraham.varric...@googlemail.com wrote: ... Thank you for your reply Jerome. I was hoping that I could join in the development of the API or something, but if it's more than a year old ... The test applications in libdrm bug me. I can understand that development was started with intel hardware, but is it possible to make the 2 tests, well, more generic? Or is it that if someone else attempts to use GEM to support non-intel hardware, they'll have to write up their own test applications? That just sounds like a waste of effort to me. i.e. a new set of test applications for every new hardware. Am I understanding things correctly here, or did I miss something? The test apps currently only work on intel, because that's the only place they've been developed. There's nothing inherently intel specific about modetest.c, except that it hard codes calls to the intel memory manager. If you want to support multiple types of graphics hw, you would start by abstracting out the few lines that allocate the front buffer. Then you can use libudev (drm_open_matching in tests/drmtest.c) to discover drm devices and determine their pci id, and from that determine which allocation function to use. cheers, Kristian -- Stay on top of everything new and different, both inside and around Java (TM) technology - register by April 22, and save $200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco. 300 plus technical and hands-on sessions. Register today. Use priority code J9JMT32. http://p.sf.net/sfu/p -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Remove code for tracking per-drawable cliprects.
On Wed, 2009-04-08 at 04:11 +0100, Dave Airlie wrote: Do you want to pick it up then or do you want Dave to take it? Since it wasn't in my driver, I was assuming airlied would pick it up. Yup I'll grab it, I was going to leave it for the next merge window as I dislike doing anything like this post-merge, and it arrived during this merge. Cool, thanks. Kristian -- This SF.net email is sponsored by: High Quality Requirements in a Collaborative Environment. Download a free trial of Rational Requirements Composer Now! http://p.sf.net/sfu/www-ibm-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Remove code for tracking per-drawable cliprects.
On Wed, Apr 08, 2009 at 09:29:04AM -0400, Kristian Høgsberg wrote: On Wed, 2009-04-08 at 04:11 +0100, Dave Airlie wrote: Do you want to pick it up then or do you want Dave to take it? Since it wasn't in my driver, I was assuming airlied would pick it up. Yup I'll grab it, I was going to leave it for the next merge window as I dislike doing anything like this post-merge, and it arrived during this merge. I did compile and test this one, but against the old headers (in /lib/modules/...) that still had the drawable spinlock and idr in the struct drm_device. So my testing didn't catch that I left the initialization code in drm_fill_in_dev(). Here's an updated patch. cheers, Kristian From eb1299fca3de5f0c247b100180e509dc167faf0c Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= k...@redhat.com Date: Thu, 2 Apr 2009 14:21:10 -0400 Subject: [PATCH 1/2] Remove code for tracking per-drawable cliprects. MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit This was only used by the i915 driver for the swapbuffer vsync tasklet. That functionality is now gone and nothing uses the kernel side cliprects anymore. Just stub out the ioctls, but make sure we return a non-zero handle in the DRM_IOCTL_ADD_DRAW case. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/Makefile |2 +- drivers/gpu/drm/drm_drawable.c | 201 drivers/gpu/drm/drm_drv.c |5 +- drivers/gpu/drm/drm_ioctl.c| 13 +++ drivers/gpu/drm/drm_stub.c |3 - include/drm/drmP.h |8 -- 6 files changed, 16 insertions(+), 216 deletions(-) delete mode 100644 drivers/gpu/drm/drm_drawable.c diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 4ec5061..094ca09 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -5,7 +5,7 @@ ccflags-y := -Iinclude/drm drm-y := drm_auth.o drm_bufs.o drm_cache.o \ - drm_context.o drm_dma.o drm_drawable.o \ + drm_context.o drm_dma.o \ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ diff --git a/drivers/gpu/drm/drm_drawable.c b/drivers/gpu/drm/drm_drawable.c deleted file mode 100644 index 80be1ca..000 --- a/drivers/gpu/drm/drm_drawable.c +++ /dev/null @@ -1,201 +0,0 @@ -/** - * \file drm_drawable.c - * IOCTLs for drawables - * - * \author Rickard E. (Rik) Faith fa...@valinux.com - * \author Gareth Hughes gar...@valinux.com - * \author Michel Dänzer mic...@tungstengraphics.com - */ - -/* - * Created: Tue Feb 2 08:37:54 1999 by fa...@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, North Dakota. - * All Rights Reserved. - * - * 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 - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. - */ - -#include drmP.h - -/** - * Allocate drawable ID and memory to store information about it. - */ -int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - unsigned long irqflags; - struct drm_draw *draw = data; - int new_id = 0; - int ret; - -again: - if (idr_pre_get(dev-drw_idr, GFP_KERNEL) == 0) { - DRM_ERROR(Out of memory expanding drawable idr\n); - return -ENOMEM; - } - - spin_lock_irqsave(dev-drw_lock, irqflags); - ret = idr_get_new_above(dev-drw_idr, NULL, 1, new_id); - if (ret == -EAGAIN) { - spin_unlock_irqrestore(dev-drw_lock, irqflags); - goto again; - } - - spin_unlock_irqrestore(dev-drw_lock, irqflags); - - draw-handle = new_id; - - DRM_DEBUG(%d\n, draw
Re: [PATCH] Remove code for tracking per-drawable cliprects.
On Fri, Apr 3, 2009 at 11:56 AM, Kristian Høgsberg k...@bitplanet.net wrote: 2009/4/2 Eric Anholt e...@anholt.net: On Thu, 2009-04-02 at 14:41 -0400, Kristian Høgsberg wrote: This was only used by the i915 driver for the swapbuffer vsync tasklet. That functionality is now gone and nothing uses the kernel side cliprects anymore. Just stub out the ioctls, but make sure we return a non-zero handle in the DRM_IOCTL_ADD_DRAW case. Have you tested old userland to make sure it doesn't freak out? Other than that, I love the idea. I did, ran gears, resized it, and it worked. glxgears is even less of a test suite than it is a benchmark, of course, bu int this case I do believe it tests the code paths in question. The only gotchas would be if some userspace code relies on updating or removing an invalid drawable handle to return -EINVAL or relies on adddraw returning unique drawable handles. In my reading of the xf86dri, aiglx and libgl, I've not come across any such requirement. Do you want to pick it up then or do you want Dave to take it? thanks, Kristian -- This SF.net email is sponsored by: High Quality Requirements in a Collaborative Environment. Download a free trial of Rational Requirements Composer Now! http://p.sf.net/sfu/www-ibm-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Remove code for tracking per-drawable cliprects.
2009/4/2 Eric Anholt e...@anholt.net: On Thu, 2009-04-02 at 14:41 -0400, Kristian Høgsberg wrote: This was only used by the i915 driver for the swapbuffer vsync tasklet. That functionality is now gone and nothing uses the kernel side cliprects anymore. Just stub out the ioctls, but make sure we return a non-zero handle in the DRM_IOCTL_ADD_DRAW case. Have you tested old userland to make sure it doesn't freak out? Other than that, I love the idea. I did, ran gears, resized it, and it worked. glxgears is even less of a test suite than it is a benchmark, of course, bu int this case I do believe it tests the code paths in question. The only gotchas would be if some userspace code relies on updating or removing an invalid drawable handle to return -EINVAL or relies on adddraw returning unique drawable handles. In my reading of the xf86dri, aiglx and libgl, I've not come across any such requirement. cheers, Kristian -- -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] Remove code for tracking per-drawable cliprects.
This was only used by the i915 driver for the swapbuffer vsync tasklet. That functionality is now gone and nothing uses the kernel side cliprects anymore. Just stub out the ioctls, but make sure we return a non-zero handle in the DRM_IOCTL_ADD_DRAW case. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/Makefile |2 +- drivers/gpu/drm/drm_drawable.c | 201 drivers/gpu/drm/drm_drv.c |5 +- drivers/gpu/drm/drm_ioctl.c| 13 +++ include/drm/drmP.h |8 -- 5 files changed, 16 insertions(+), 213 deletions(-) delete mode 100644 drivers/gpu/drm/drm_drawable.c diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 4ec5061..094ca09 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -5,7 +5,7 @@ ccflags-y := -Iinclude/drm drm-y := drm_auth.o drm_bufs.o drm_cache.o \ - drm_context.o drm_dma.o drm_drawable.o \ + drm_context.o drm_dma.o \ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \ drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ diff --git a/drivers/gpu/drm/drm_drawable.c b/drivers/gpu/drm/drm_drawable.c deleted file mode 100644 index 80be1ca..000 --- a/drivers/gpu/drm/drm_drawable.c +++ /dev/null @@ -1,201 +0,0 @@ -/** - * \file drm_drawable.c - * IOCTLs for drawables - * - * \author Rickard E. (Rik) Faith fa...@valinux.com - * \author Gareth Hughes gar...@valinux.com - * \author Michel Dänzer mic...@tungstengraphics.com - */ - -/* - * Created: Tue Feb 2 08:37:54 1999 by fa...@valinux.com - * - * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. - * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, North Dakota. - * All Rights Reserved. - * - * 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 - * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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. - */ - -#include drmP.h - -/** - * Allocate drawable ID and memory to store information about it. - */ -int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - unsigned long irqflags; - struct drm_draw *draw = data; - int new_id = 0; - int ret; - -again: - if (idr_pre_get(dev-drw_idr, GFP_KERNEL) == 0) { - DRM_ERROR(Out of memory expanding drawable idr\n); - return -ENOMEM; - } - - spin_lock_irqsave(dev-drw_lock, irqflags); - ret = idr_get_new_above(dev-drw_idr, NULL, 1, new_id); - if (ret == -EAGAIN) { - spin_unlock_irqrestore(dev-drw_lock, irqflags); - goto again; - } - - spin_unlock_irqrestore(dev-drw_lock, irqflags); - - draw-handle = new_id; - - DRM_DEBUG(%d\n, draw-handle); - - return 0; -} - -/** - * Free drawable ID and memory to store information about it. - */ -int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_draw *draw = data; - unsigned long irqflags; - struct drm_drawable_info *info; - - spin_lock_irqsave(dev-drw_lock, irqflags); - - info = drm_get_drawable_info(dev, draw-handle); - if (info == NULL) { - spin_unlock_irqrestore(dev-drw_lock, irqflags); - return -EINVAL; - } - drm_free(info-rects, info-num_rects * sizeof(struct drm_clip_rect), - DRM_MEM_BUFS); - drm_free(info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); - - idr_remove(dev-drw_idr, draw-handle); - - spin_unlock_irqrestore(dev-drw_lock, irqflags); - DRM_DEBUG(%d\n, draw-handle); - return 0; -} - -int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file *file_priv) -{ - struct drm_update_draw *update = data; - unsigned long irqflags
Re: DRI2 + buffer creation
On Tue, Mar 31, 2009 at 4:46 AM, Alan Hourihane al...@fairlite.co.uk wrote: On Tue, 2009-03-31 at 15:43 +1000, Dave Airlie wrote: So I've been playing a bit more with DRI2 and I'm having trouble finding how the buffer creation was meant to work for depth buffers. If my app uses a visual 0xbc 24 tc 0 24 0 r . . 8 8 8 0 0 16 0 0 0 0 0 0 0 None which is 24-bits + 16-bit depth, I don't have enough information in the DDX to create a depth buffer with a cpp of 2, the DDX can only see the drawable information it knows nothing about the visual. Now it goes and creates a set of 4 buffers to give back to Mesa, which then goes and takes the cpp of the depth buffer as 4 when clearly it would need to be 2, then bad things happen. So should I just be creating the depth buffer in Mesa, does the DDX need to know about it all really... Yep, go create the depth buffer in Mesa. The DDX doesn't really need to know about it. Creating the depth buffer and the other aux buffers through the X server is more complicated, but it was done that way for a reason. Two different client can render to the same GLX drawable and in that case they need to share the aux buffers for the drawable. I considered letting the DRI driver create the buffers, but in that case it needs to tell the X server about it, and then you get extra roundtrips and races between DRI clients to create the buffers. So creating them in the X server is the simplest solution, given what we have to support. As it is, the hw specific part of X creates the buffers from the tokens passed in by the DRI driver and can implement whichever convention the DRI driver expects. For example, for intel, if both depth and stencil are requested, the DDX driver knows to only allocate one BO for the two buffers and the DRI driver expects this. Likewise, if radeon expects a 16 bit depth buffer when there is no stencil, that's the behaviour the DDX should implement. If a situation arises where a combination of buffers required for a visual doesn't uniquely imply which buffer sizes are expected (say, a fbconfig without stencil could use either a 16 bit or a 32 bit depth buffer), we need to introduce new DRI2 buffer tokens along the lines of Depth16 and Depth32 so the DRI driver can communicate which one it wants. cheers, Kristian -- -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: DRI2 + buffer creation
2009/3/31 Dave Airlie airl...@gmail.com: 2009/3/31 Kristian Høgsberg k...@bitplanet.net: On Tue, Mar 31, 2009 at 4:46 AM, Alan Hourihane al...@fairlite.co.uk wrote: On Tue, 2009-03-31 at 15:43 +1000, Dave Airlie wrote: So I've been playing a bit more with DRI2 and I'm having trouble finding how the buffer creation was meant to work for depth buffers. If my app uses a visual 0xbc 24 tc 0 24 0 r . . 8 8 8 0 0 16 0 0 0 0 0 0 0 None which is 24-bits + 16-bit depth, I don't have enough information in the DDX to create a depth buffer with a cpp of 2, the DDX can only see the drawable information it knows nothing about the visual. Now it goes and creates a set of 4 buffers to give back to Mesa, which then goes and takes the cpp of the depth buffer as 4 when clearly it would need to be 2, then bad things happen. So should I just be creating the depth buffer in Mesa, does the DDX need to know about it all really... Yep, go create the depth buffer in Mesa. The DDX doesn't really need to know about it. Creating the depth buffer and the other aux buffers through the X server is more complicated, but it was done that way for a reason. Two different client can render to the same GLX drawable and in that case they need to share the aux buffers for the drawable. I considered letting the DRI driver create the buffers, but in that case it needs to tell the X server about it, and then you get extra roundtrips and races between DRI clients to create the buffers. So creating them in the X server is the simplest solution, given what we have to support. As it is, the hw specific part of X creates the buffers from the tokens passed in by the DRI driver and can implement whichever convention the DRI driver expects. For example, for intel, if both depth and stencil are requested, the DDX driver knows to only allocate one BO for the two buffers and the DRI driver expects this. Likewise, if radeon expects a 16 bit depth buffer when there is no stencil, that's the behaviour the DDX should implement. If a situation arises where a combination of buffers required for a visual doesn't uniquely imply which buffer sizes are expected (say, a fbconfig without stencil could use either a 16i bit or a 32 bit depth buffer), we need to introduce new DRI2 buffer tokens along the lines of Depth16 and Depth32 so the DRI driver can communicate which one it wants. But you don't give the DDX enough information to make this decision, I get the drawable, an attachments list and a count, I don't get the visual or fbconfig. Now radeon isn't special Intel has the same bug. Most GPUs have 3 cases they can deal with, z24s8, z24, z16. However if I pick a z16 visual there is no way the DDX can differentiate this from a z24, all it gets is a drawable. It then uses CreatePixmap which creates a pixmap that is 2x too large, wasting VRAM, and with the wrong bpp component. What I've done now is intercept it on the mesa side and hack the bpp down to 2, but this still wastes memory and ignores the actual problem that the DDX doesn't have the info to make the correct decision. That's the case I was describing in the last sentence. When the DDX gets the set of buffers to allocate it doesn't know whether to allocate 16 or 24 bit depth buffer. What I'm suggesting is that we add a new buffer token to the DRI2 protocol, DRI2BufferDepth16, which the dri driver can use to indicate that it wants a 16 bit depth buffer even if the drawable is 24 bpp. It requires a dri2 proto bump, and the loader needs to tell the dri driver that the DRI2BufferDepth16 token is available. cheers, Kristian -- -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] libdrm: speed up connector mode fetching
2009/3/31 Eric Anholt e...@anholt.net: On Fri, 2009-03-27 at 15:48 -0700, Jesse Barnes wrote: On Fri, 27 Mar 2009 22:53:00 +0100 Jakob Bornecrantz wallbra...@gmail.com wrote: On Fri, Mar 27, 2009 at 8:58 PM, Jesse Barnes jbar...@virtuousgeek.org wrote: This patch speeds up drmModeGetConnector by pre-allocating mode property info space before calling into the kernel. In many cases this pre-allocation will be sufficient to hold the returned values (it's easy enough to tweak if the common case becomes larger), which means we don't have to make the second call, which saves a lot of time. Any comments or problems with the patch? Looks good, I do wonder how much time do we save on doing pre allocation, just curious? Anyways the patch is Acked-by: Jakob Bornecrantz wallbra...@gmail.com Cheers Jakob. Some of my testing showed it took about .3s for a drmModeGetConnector call and my testing showed this decrease a lot with the pre-allocation (conveniently lost the test results though). Theoretically it should be about half the cost with pre-allocation, which adds up if you multiply by the number of outputs. Seems like the ioctl needs a flag for did the user want me to go reprobe things? like we did in the X Server. Yes, please, I've been pushing for that too. cheers, Kristian -- -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Fix deadlock in drm_setmaster_ioctl
On Wed, Mar 4, 2009 at 6:50 AM, Dave Airlie airl...@linux.ie wrote: Fix deadlock in drm_setmaster_ioctl Wow, I have this right in my rawhide tree, I must have retyped this when I ported it back. We need to bump the dri version for this so we don't deadlock on older kernels when the 2d drivers start using this. A second non-kms X server would just fail to initialize DRI before, when we add drmSetMaster() support they will deadlock if we don't make it conditional on whether or not the kernel has this fix. cheers, Kristian -- 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] mesa/intel: add DRI2 swapbuffers interface
On Fri, Feb 27, 2009 at 2:22 PM, Jesse Barnes jbar...@virtuousgeek.org wrote: On Thursday, February 26, 2009 1:31:03 pm Jesse Barnes wrote: Add support to Mesa and the intel driver for the new DRI2 swapbuffers interface. Uses the new flush hook to make sure any outstanding rendering is complete before sending the swapbuffers request. Need to update the FBconfigs too; we now support the exchange method. -- Jesse Barnes, Intel Open Source Technology Center diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index a726b93..b663028 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -681,6 +681,9 @@ struct __DRIdri2ExtensionRec { __DRIcontext *shared, void *loaderPrivate); + void (*setBuffers)(__DRIdrawable *drawable, + __DRIbuffer *buffers, + int count); }; We don't need setBuffers, we can just require the flush extension. When the flush entry point is called, mark the buffers as invalid which will cause the dri driver to call getBuffers() before doing any further rendering. @@ -223,8 +226,40 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, static void dri2SwapBuffers(__GLXDRIdrawable *pdraw) { __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw; + __GLXdisplayPrivate *dpyPriv = __glXInitialize(priv-base.psc-dpy); + __GLXDRIdisplayPrivate *pdp = + (__GLXDRIdisplayPrivate *)dpyPriv-dri2Display; + __GLXscreenConfigs *psc = pdraw-psc; + DRI2Buffer *buffers; + int i, count; + +#ifdef __DRI2_FLUSH + if (pdraw-psc-f) + (*pdraw-psc-f-flush)(pdraw-driDrawable); +#endif + + /* 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 || !count) + return dri2CopySubBuffer(pdraw, 0, 0, priv-width, priv-height); As for the AIGLX case, DRI2SwapBuffers should swap the buffers or fallback to CopyRegion in the server. This requires an extra round trip in the fallback case and we have implement the fallback logic everywhere we use DRI2SwapBuffers instead of just once in the server. cheers, Kristian -- 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: changes to upstreaming process for Linux code.
On Fri, Feb 27, 2009 at 4:40 PM, Dave Airlie airl...@linux.ie wrote: Prompted by how well it worked with Intel, and changes in my personal life leading to reduced time availability (except at 4am...) I'm going to clarify the process for getting patches upstream now. (a...@amd also trialed this to get r600 upstream). 1. Apart from maybe minor changes I will no longer pull drm.git patches into Linux kernel tree automatically. 2. All patches should be sent to dri-devel and me against my drm-next tree. 3. Patches must conform to kernel coding standards and have acceptable checkpatch.pl results. My only major issues with checkpatch.pl is 80 char line length restrictions, please try your best but don't make the code really ugly to achieve this. Some scripts/people are too anal. This also means no kernel version checks upstream (however we might be able to convince people about this, if we get build from Linus tree working). 4. I will accept sub-module maintainers who want to maintain their driver in a git tree, but it'll take a bit of time for me to trust you that I'll pull directly, and patches should still pass by the list. Ask Eric how to do this. 5. if someone wants to step up and maintain drm.git as a going concern let me know, I'm glad to help if I can. Sounds good to me - one question: should we divorce libdrm from the drm.git repo? cheers, Kristian -- 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: [Mesa3d-dev] DRI2 flush extension
On Thu, Feb 19, 2009 at 8:46 PM, Alan Hourihane al...@fairlite.co.uk wrote: Attached is a new DRI2 flush extension that allows the driver to perform a real flush before dispatching a swap or Xserver copy operation. Currently we do this before a DRI2CopyRegion() call. This allows drivers a real end of scene flush to ensure rendering is complete prior to a swap. I've committed this already to the gallium-mesa-7.4 branch, but any comments appreciated before I push to the master branch? Hi Alan, A couple of comments below. commit b163d4f9ee2ab4d54daf7c17c097cae51c9c6db2 Author: Alan Hourihane al...@vmware.com Date: Thu Feb 19 18:39:08 2009 + glx: add support for a reallyFlush() function before swap occurs. diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 27cc1be..a726b93 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -78,6 +78,7 @@ typedef struct __DRIswrastExtensionRec __DRIswrastExtension; typedef struct __DRIbufferRec __DRIbuffer; typedef struct __DRIdri2ExtensionRec __DRIdri2Extension; typedef struct __DRIdri2LoaderExtensionRec __DRIdri2LoaderExtension; +typedef struct __DRI2flushExtensionRec __DRI2flushExtension; /*...@}*/ @@ -245,6 +246,16 @@ struct __DRItexBufferExtensionRec { __DRIdrawable *pDraw); }; +/** + * Used by drivers that implement DRI2 + */ +#define __DRI2_FLUSH DRI2_Flush +#define __DRI2_FLUSH_VERSION 1 +struct __DRI2flushExtensionRec { +__DRIextension base; +void (*flush)(__DRIdrawable *drawable); +}; + /** * XML document describing the configuration options supported by the diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c index 639aa19..fdda852 100644 --- a/src/glx/x11/dri2_glx.c +++ b/src/glx/x11/dri2_glx.c @@ -207,7 +207,13 @@ static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw, xrect.width = width; xrect.height = height; +#ifdef __DRI2_FLUSH +if (pdraw-psc-f) + (*pdraw-psc-f-flush)(pdraw-driDrawable); +#endif + region = XFixesCreateRegion(pdraw-psc-dpy, xrect, 1); +/* should get a fence ID back from here at some point */ DRI2CopyRegion(pdraw-psc-dpy, pdraw-drawable, region, DRI2BufferFrontLeft, DRI2BufferBackLeft); XFixesDestroyRegion(pdraw-psc-dpy, region); @@ -235,6 +241,11 @@ static void dri2WaitX(__GLXDRIdrawable *pdraw) xrect.width = priv-width; xrect.height = priv-height; +#ifdef __DRI2_FLUSH +if (pdraw-psc-f) + (*pdraw-psc-f-flush)(pdraw-driDrawable); +#endif + This flush call isn't necessary - glXWaitX() is called to wait for X rendering to the drawable to finish so there can't be any unflushed DRI driver activity. region = XFixesCreateRegion(pdraw-psc-dpy, xrect, 1); DRI2CopyRegion(pdraw-psc-dpy, pdraw-drawable, region, DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft); @@ -255,6 +266,11 @@ static void dri2WaitGL(__GLXDRIdrawable *pdraw) xrect.width = priv-width; xrect.height = priv-height; +#ifdef __DRI2_FLUSH +if (pdraw-psc-f) + (*pdraw-psc-f-flush)(pdraw-driDrawable); +#endif + region = XFixesCreateRegion(pdraw-psc-dpy, xrect, 1); DRI2CopyRegion(pdraw-psc-dpy, pdraw-drawable, region, DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft); diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c index 4fda649..90c3d8c 100644 --- a/src/glx/x11/dri_common.c +++ b/src/glx/x11/dri_common.c @@ -392,6 +392,13 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2) } #endif +#ifdef __DRI2_FLUSH + if ((strcmp(extensions[i]-name, __DRI2_FLUSH) == 0) dri2) { + psc-f = (__DRI2flushExtension *) extensions[i]; + /* internal driver extension, no GL extension exposed */ + } +#endif The driver needs to know whether the loader is new enough that it supports the flush extension so that it can enable the lazy glFlush() optiomization. An older loader will just ignore the flush extension and thus never call that entry point, in which case the driver must flush on every glFlush() call. The only way to do this I can think of right now is to add an 'enable()' entrypoint to the extension to tell the driver that the loader will call -flush() and it's ok to ignore glFlush(). /* Ignore unknown extensions */ } } diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h index 3e70759..caf58bb 100644 --- a/src/glx/x11/glxclient.h +++ b/src/glx/x11/glxclient.h @@ -519,6 +519,10 @@ struct __GLXscreenConfigsRec { const __DRItexBufferExtension *texBuffer; #endif +#ifdef __DRI2_FLUSH +const __DRI2flushExtension *f; +#endif + #endif /** -- Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA -OSBC tackles the biggest issue in open source: Open Sourcing the
Re: [PATCH] drm: Take mmap_sem up front to avoid lock order violations.
On Thu, 2009-02-19 at 11:33 +0100, Peter Zijlstra wrote: On Thu, 2009-02-19 at 10:19 +0100, Peter Zijlstra wrote: On Wed, 2009-02-18 at 11:38 -0500, k...@bitplanet.net wrote: From: Kristian Høgsberg k...@redhat.com A number of GEM operations (and legacy drm ones) want to copy data to or from userspace while holding the struct_mutex lock. However, the fault handler calls us with the mmap_sem held and thus enforces the opposite locking order. This patch downs the mmap_sem up front for those operations that access userspace data under the struct_mutex lock to ensure the locking order is consistent. Signed-off-by: Kristian Høgsberg k...@redhat.com --- Here's a different and simpler attempt to fix the locking order problem. We can just down_read() the mmap_sem pre-emptively up-front, and the locking order is respected. It's simpler than the mutex_trylock() game, avoids introducing a new mutex. OK let me try that again -- my initial response was a tad curt :/ No that's fair, I was aware that the patch was probably borderline and got the feedback I was looking for ;) While I appreciate your efforts in fixing GEM (I too have an interest in seeing it done), I cannot support your patch. Firstly, you're using mmap_sem well outside its problem domain, this is bad form. Furthermore, holding it for extended durations for no good reason affects all other users. Yup, agree. Secondly, mmap_sem is not a recursive lock (very few kernel locks are, and we generally frown upon recursive locking schemes), this means that the fault handler still cannot function properly. I understand, but we take it twice only as a read lock, so that should work, right? We prevent the deadlock the lockdep validator warned about and as far as I can see, the patch doesn't introduce a new one. But other than that I agree with the frowning on recursive locking, it's too often used to paper over badly thought out locking. cheers, Kristian -- 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: Take mmap_sem up front to avoid lock order violations.
On Thu, 2009-02-19 at 16:17 +0100, Nick Piggin wrote: On Thu, Feb 19, 2009 at 09:49:40AM -0500, Kristian Høgsberg wrote: Secondly, mmap_sem is not a recursive lock (very few kernel locks are, and we generally frown upon recursive locking schemes), this means that the fault handler still cannot function properly. I understand, but we take it twice only as a read lock, so that should work, right? We prevent the deadlock the lockdep validator warned about and as far as I can see, the patch doesn't introduce a new one. But other than that I agree with the frowning on recursive locking, it's too often used to paper over badly thought out locking. It doesn't work. rwsems are fair (otherwise there is terrible starvation properties), so if another process does an interleaved down_write, then the 2nd down_read will block until the down_write is serviced. Ooh, right, yes of course, ouch. thanks, Kristian -- 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: Take mmap_sem up front to avoid lock order violations.
On Wed, Feb 18, 2009 at 12:36 PM, Eric Anholt e...@anholt.net wrote: On Wed, 2009-02-18 at 11:02 -0500, k...@bitplanet.net wrote: From: Kristian Høgsberg k...@redhat.com A number of GEM operations (and legacy drm ones) want to copy data to or from userspace while holding the struct_mutex lock. However, the fault handler calls us with the mmap_sem held and thus enforces the opposite locking order. This patch downs the mmap_sem up front for those operations that access userspace data under the struct_mutex lock to ensure the locking order is consistent. Signed-off-by: Kristian Høgsberg k...@redhat.com Have you tested this against actually faulting? My understanding was that you can't recurse on mmap_sem. I tested it and it worked, but didn't add code to detect contention so I can't say for sure I hit that case. mmap_sem is a read/write semaphore, so while we can't recurse, we can get away with taking two reader locks. cheers, Kristian -- 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: Take mmap_sem up front to avoid lock order violations.
On Wed, Feb 18, 2009 at 5:42 PM, Thomas Hellström tho...@shipmail.org wrote: Kristian Høgsberg wrote: On Wed, Feb 18, 2009 at 12:36 PM, Eric Anholt e...@anholt.net wrote: On Wed, 2009-02-18 at 11:02 -0500, k...@bitplanet.net wrote: From: Kristian Høgsberg k...@redhat.com A number of GEM operations (and legacy drm ones) want to copy data to or from userspace while holding the struct_mutex lock. However, the fault handler calls us with the mmap_sem held and thus enforces the opposite locking order. This patch downs the mmap_sem up front for those operations that access userspace data under the struct_mutex lock to ensure the locking order is consistent. Signed-off-by: Kristian Høgsberg k...@redhat.com Have you tested this against actually faulting? My understanding was that you can't recurse on mmap_sem. I tested it and it worked, but didn't add code to detect contention so I can't say for sure I hit that case. mmap_sem is a read/write semaphore, so while we can't recurse, we can get away with taking two reader locks. cheers, Kristian Kristian, This seems a bit odd to me. The extra lock taking does not prevent any deadlocks, so is this done to only silence a warning message? A reversed locking order between a mutex and an rwsem can never deadlock if the rwsem is only taken in read mode. If the mutex is taken simultaneously as the rwsem in _write_ mode then that locking order must be preserved across the code, even when the rwsem is taken in read mode. If all we ever did was read, we wouldn't need the mmap_sem at all... The point is that somebody could be holding the semaphore in write mode in which case taking the mmap_sem in read mode blocks. So if we're called with the mmap_sem held in write mode and we going to take the struct_lock mutex, but gem_execbuffer preempts, takes the struct_mutex and then tries to call copy_from_user(), we deadlock. Taking the mmap_sem in read mode early as in my patch, prevents this. In this case, I guess the fault handler is always only called with mmap_sem held in read mode, and then yes, there's no deadlock and the warning is harmless. That doesn't mean that it's a good idea - enforcing a consistent lock order is good practice that keeps the code clean and makes it easy to verify locking without knowing every part of the system in detail. And should the fault callback mmap_sem assumptions change in the future, gem will certainly be more robust if we keep the locking simple. cheers, Kristian -- 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 1/4] drm: Add locking around cursor gem operations.
We need to hold the struct_mutex around pinning and the phys object operations. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/i915/intel_display.c |9 + 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ac92799..94c7c09 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1043,18 +1043,19 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, } /* we only need to pin inside GTT if cursor is non-phy */ + mutex_lock(dev-struct_mutex); if (!dev_priv-cursor_needs_physical) { ret = i915_gem_object_pin(bo, PAGE_SIZE); if (ret) { DRM_ERROR(failed to pin cursor bo\n); - goto fail; + goto fail_locked; } addr = obj_priv-gtt_offset; } else { ret = i915_gem_attach_phys_object(dev, bo, (pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); if (ret) { DRM_ERROR(failed to attach phys object\n); - goto fail; + goto fail_locked; } addr = obj_priv-phys_obj-handle-busaddr; } @@ -1074,10 +1075,9 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, i915_gem_detach_phys_object(dev, intel_crtc-cursor_bo); } else i915_gem_object_unpin(intel_crtc-cursor_bo); - mutex_lock(dev-struct_mutex); drm_gem_object_unreference(intel_crtc-cursor_bo); - mutex_unlock(dev-struct_mutex); } + mutex_unlock(dev-struct_mutex); intel_crtc-cursor_addr = addr; intel_crtc-cursor_bo = bo; @@ -1085,6 +1085,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, return 0; fail: mutex_lock(dev-struct_mutex); +fail_locked: drm_gem_object_unreference(bo); mutex_unlock(dev-struct_mutex); return ret; -- 1.6.0.rc0.42.g186458 -- 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 2/4] drm: Bring PLL limits in sync with DDX values.
Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/i915/intel_display.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 94c7c09..4f54ac5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -90,12 +90,12 @@ typedef struct { #define I9XX_DOT_MAX40 #define I9XX_VCO_MIN 140 #define I9XX_VCO_MAX 280 -#define I9XX_N_MIN 3 -#define I9XX_N_MAX 8 +#define I9XX_N_MIN 1 +#define I9XX_N_MAX 6 #define I9XX_M_MIN 70 #define I9XX_M_MAX 120 #define I9XX_M1_MIN 10 -#define I9XX_M1_MAX 20 +#define I9XX_M1_MAX 22 #define I9XX_M2_MIN 5 #define I9XX_M2_MAX 9 #define I9XX_P_SDVO_DAC_MIN 5 -- 1.6.0.rc0.42.g186458 -- 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 3/4] drm: Collapse identical i8xx_clock() and i9xx_clock().
They used to be different. Now they're identical. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/i915/intel_display.c | 33 ++--- 1 files changed, 6 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4f54ac5..8b20387 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -189,19 +189,7 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) return limit; } -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ - -static void i8xx_clock(int refclk, intel_clock_t *clock) -{ - clock-m = 5 * (clock-m1 + 2) + (clock-m2 + 2); - clock-p = clock-p1 * clock-p2; - clock-vco = refclk * clock-m / (clock-n + 2); - clock-dot = clock-vco / clock-p; -} - -/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ - -static void i9xx_clock(int refclk, intel_clock_t *clock) +static void intel_clock(int refclk, intel_clock_t *clock) { clock-m = 5 * (clock-m1 + 2) + (clock-m2 + 2); clock-p = clock-p1 * clock-p2; @@ -209,15 +197,6 @@ static void i9xx_clock(int refclk, intel_clock_t *clock) clock-dot = clock-vco / clock-p; } -static void intel_clock(struct drm_device *dev, int refclk, - intel_clock_t *clock) -{ - if (IS_I9XX(dev)) - i9xx_clock (refclk, clock); - else - i8xx_clock (refclk, clock); -} - /** * Returns whether any output on the specified pipe is of the specified type */ @@ -318,7 +297,7 @@ static bool intel_find_best_PLL(struct drm_crtc *crtc, int target, clock.p1 = limit-p1.max; clock.p1++) { int this_err; - intel_clock(dev, refclk, clock); + intel_clock(refclk, clock); if (!intel_PLL_is_valid(crtc, clock)) continue; @@ -1313,7 +1292,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) } /* XXX: Handle the 100Mhz refclk */ - i9xx_clock(96000, clock); + intel_clock(96000, clock); } else { bool is_lvds = (pipe == 1) (I915_READ(LVDS) LVDS_PORT_EN); @@ -1325,9 +1304,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) if ((dpll PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) { /* XXX: might not be 66MHz */ - i8xx_clock(66000, clock); + intel_clock(66000, clock); } else - i8xx_clock(48000, clock); + intel_clock(48000, clock); } else { if (dpll PLL_P1_DIVIDE_BY_TWO) clock.p1 = 2; @@ -1340,7 +1319,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) else clock.p2 = 2; - i8xx_clock(48000, clock); + intel_clock(48000, clock); } } -- 1.6.0.rc0.42.g186458 -- 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 4/4] drm: Use spread spectrum when the bios tells us it's ok.
Lifted from the DDX modesetting. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/i915/i915_drv.h |2 ++ drivers/gpu/drm/i915/intel_bios.c|8 drivers/gpu/drm/i915/intel_display.c | 20 ++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7325363..135a08f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -184,6 +184,8 @@ typedef struct drm_i915_private { unsigned int lvds_dither:1; unsigned int lvds_vbt:1; unsigned int int_crt_support:1; + unsigned int lvds_use_ssc:1; + int lvds_ssc_freq; struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 4ca82a0..65be30d 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -135,6 +135,14 @@ parse_general_features(struct drm_i915_private *dev_priv, if (general) { dev_priv-int_tv_support = general-int_tv_support; dev_priv-int_crt_support = general-int_crt_support; + dev_priv-lvds_use_ssc = general-enable_ssc; + + if (dev_priv-lvds_use_ssc) { + if (IS_I855(dev_priv-dev)) + dev_priv-lvds_ssc_freq = general-ssc_freq ? 66 : 48; + else + dev_priv-lvds_ssc_freq = general-ssc_freq ? 100 : 96; + } } } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8b20387..13f9b66 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -217,7 +217,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type) return false; } -#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; } +#define INTELPllInvalid(s) do { DRM_DEBUG(s); return false; } while (0) /** * Returns whether the given set of divisors are valid for a given refclk with * the given connectors. @@ -726,7 +726,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE; int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS; int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int refclk; + int refclk, num_outputs = 0; intel_clock_t clock; u32 dpll = 0, fp = 0, dspcntr, pipeconf; bool ok, is_sdvo = false, is_dvo = false; @@ -763,9 +763,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, is_crt = true; break; } + + num_outputs++; } - if (IS_I9XX(dev)) { + if (is_lvds dev_priv-lvds_use_ssc num_outputs 2) { + refclk = dev_priv-lvds_ssc_freq * 1000; + DRM_DEBUG(using SSC reference clock of %d MHz\n, refclk / 1000); + } else if (IS_I9XX(dev)) { refclk = 96000; } else { refclk = 48000; @@ -824,11 +829,14 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } } - if (is_tv) { + if (is_sdvo is_tv) + dpll |= PLL_REF_INPUT_TVCLKINBC; + else if (is_tv) /* XXX: just matching BIOS for now */ -/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ + /* dpll |= PLL_REF_INPUT_TVCLKINBC; */ dpll |= 3; - } + else if (is_lvds dev_priv-lvds_use_ssc num_outputs 2) + dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; else dpll |= PLL_REF_INPUT_DREFCLK; -- 1.6.0.rc0.42.g186458 -- 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] Release user fbs in drm_release
Avoids leaking fbs and associated buffers on release. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_crtc.c |3 +-- drivers/gpu/drm/drm_fops.c |3 +++ include/drm/drm_crtc.h |2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index bfce099..94a7688 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1741,9 +1741,8 @@ out: * RETURNS: * Zero on success, errno on failure. */ -void drm_fb_release(struct file *filp) +void drm_fb_release(struct drm_file *priv) { - struct drm_file *priv = filp-private_data; struct drm_device *dev = priv-minor-dev; struct drm_framebuffer *fb, *tfb; diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index b06a537..6c020fe 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -457,6 +457,9 @@ int drm_release(struct inode *inode, struct file *filp) if (dev-driver-driver_features DRIVER_GEM) drm_gem_release(dev, file_priv); + if (dev-driver-driver_features DRIVER_MODESET) + drm_fb_release(file_priv); + mutex_lock(dev-ctxlist_mutex); if (!list_empty(dev-ctxlist)) { struct drm_ctx_list *pos, *n; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index d54de24..5ded1ac 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -609,7 +609,7 @@ extern char *drm_get_dvi_i_subconnector_name(int val); extern char *drm_get_dvi_i_select_name(int val); extern char *drm_get_tv_subconnector_name(int val); extern char *drm_get_tv_select_name(int val); -extern void drm_fb_release(struct file *filp); +extern void drm_fb_release(struct drm_file *file_priv); extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); extern struct edid *drm_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter); -- 1.6.0.rc0.42.g186458 -- -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] Restore kernelfb mode for all crtcs.
Hi, Is there anything holding this back now? I was hoping that this would get into the next pull request, it just a simple bug fix... cheers, Kristian On Wed, Feb 4, 2009 at 1:35 PM, Jesse Barnes jbar...@virtuousgeek.org wrote: On Tuesday, February 3, 2009 12:07 pm Kristian Høgsberg wrote: Record and restore the kernel framebuffer for all crtc on panic and lastclose. Signed-off-by: Kristian Høgsberg k...@redhat.com Yeah, looks good. This should give us even better panic/lastclose/sysrq behavior. Acked-by: Jesse Barnes jbar...@virtuousgeek.org -- Jesse Barnes, Intel Open Source Technology Center -- Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM) software. With Adobe AIR, Ajax developers can use existing skills and code to build responsive, highly engaging applications that combine the power of local resources and data with the reach of the web. Download the Adobe AIR SDK and Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel -- Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM) software. With Adobe AIR, Ajax developers can use existing skills and code to build responsive, highly engaging applications that combine the power of local resources and data with the reach of the web. Download the Adobe AIR SDK and Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] Restore kernelfb mode for all crtcs.
Record and restore the kernel framebuffer for all crtc on panic and lastclose. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/i915/intel_fb.c | 19 ++- 1 files changed, 14 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index afd1217..0fd76d4 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -412,7 +412,8 @@ int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc) } EXPORT_SYMBOL(intelfb_resize); -static struct drm_mode_set kernelfb_mode; +static struct drm_mode_set *kernelfb_mode[2]; +static int kernelfb_crtc_count; static int intelfb_panic(struct notifier_block *n, unsigned long ununsed, void *panic_str) @@ -688,7 +689,8 @@ static int intelfb_multi_fb_probe_crtc(struct drm_device *dev, struct drm_crtc * info-fix.id); /* Switch back to kernel console on panic */ - kernelfb_mode = *modeset; + BUG_ON(kernelfb_crtc_count = ARRAY_SIZE(kernelfb_mode)); + kernelfb_mode[kernelfb_crtc_count++] = modeset; atomic_notifier_chain_register(panic_notifier_list, paniced); printk(KERN_INFO registered panic notifier\n); @@ -701,6 +703,7 @@ static int intelfb_multi_fb_probe(struct drm_device *dev) struct drm_crtc *crtc; int ret = 0; + kernelfb_crtc_count = 0; list_for_each_entry(crtc, dev-mode_config.crtc_list, head) { ret = intelfb_multi_fb_probe_crtc(dev, crtc); if (ret) @@ -797,6 +800,7 @@ static int intelfb_single_fb_probe(struct drm_device *dev) * For each CRTC, set up the connector list for the CRTC's mode * set configuration. */ + kernelfb_crtc_count = 0; list_for_each_entry(crtc, dev-mode_config.crtc_list, head) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -824,6 +828,9 @@ static int intelfb_single_fb_probe(struct drm_device *dev) modeset-num_connectors = conn_count; if (modeset-mode != modeset-crtc-desired_mode) modeset-mode = modeset-crtc-desired_mode; + + BUG_ON(kernelfb_crtc_count = ARRAY_SIZE(kernelfb_mode)); + kernelfb_mode[kernelfb_crtc_count++] = modeset; } par-crtc_count = crtc_count; @@ -838,7 +845,6 @@ static int intelfb_single_fb_probe(struct drm_device *dev) info-fix.id); /* Switch back to kernel console on panic */ - kernelfb_mode = *modeset; atomic_notifier_chain_register(panic_notifier_list, paniced); printk(KERN_INFO registered panic notifier\n); @@ -852,7 +858,10 @@ static int intelfb_single_fb_probe(struct drm_device *dev) */ void intelfb_restore(void) { - drm_crtc_helper_set_config(kernelfb_mode); + int i; + + for (i = 0; i kernelfb_crtc_count; i++) + drm_crtc_helper_set_config(kernelfb_mode[i]); } static void intelfb_sysrq(int dummy1, struct tty_struct *dummy3) @@ -918,7 +927,7 @@ int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) } atomic_notifier_chain_unregister(panic_notifier_list, paniced); - memset(kernelfb_mode, 0, sizeof(struct drm_mode_set)); + kernelfb_crtc_count = 0; return 0; } EXPORT_SYMBOL(intelfb_remove); -- 1.6.1 -- Create and Deploy Rich Internet Apps outside the browser with Adobe(R)AIR(TM) software. With Adobe AIR, Ajax developers can use existing skills and code to build responsive, highly engaging applications that combine the power of local resources and data with the reach of the web. Download the Adobe AIR SDK and Ajax docs to start building applications today-http://p.sf.net/sfu/adobe-com -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
Re: [PATCH] drm: Drop unused and broken dri_library_name sysfs attribute.
On Thu, 2009-01-29 at 23:58 +0100, Thomas Hellström wrote: Hmm, Wasn't this at some point intended for server-free operation? I think that was John Smirls intention when he added it but it's the wrong approach. Anyway, dri_library_name is misleading since there are other dri clients than OpenGL... This is one reason, it doesn't scale. Should we have mesa_library_name, cairo_drm_driver_name, xorg_driver_name, xvmc_driver_name sysfs files? And for different chipsets the drivers will break into different .so files. One driver type may cover all of intel in one driver (like the ddx driver), other drivers may need different drivers for different intel chipsets (like mesa). So the kernel needs to know how to map the current PCI_ID to a specific driver... for every driver type we may add (we may not add a lot of driver types, though, but that doesn't make the sysfs file ok). What the kernel does, as I write in the commit message, is to extract the PCI_ID - kernel module map from the modules and then build up a map from all PCI_ID the kernel supports to the module name in a text file in /lib/modules. We can do a similar thing for standalone GL, by extracting PCI_IDs from the mesa drivers and creating a map from PCI ID to mesa driver name. Then when you're initializing you EGL driver you get the PCI ID for the device [1], figure out which driver to load and you're good. Or you can do it in a number of other ways, the point is that it's *not* the kernels jobs to track this. cheers, Kristian [1] Could be done like this: http://cgit.freedesktop.org/~krh/eagle/tree/eagle.c#n249 /Thomas Kristian Høgsberg wrote: Hey; comments on this? Can we put it in one of the git tree so it doesn't fall through the cracks? It's pretty harmless and could be merged for the 2.6.29 kernel, or we could push it the the next merge window if it's not suitable for the rc phase. Either way, we need to squash this. cheers, Kristian On Mon, Jan 5, 2009 at 4:10 PM, Kristian Høgsberg k...@redhat.com wrote: The kernel shouldn't be in the business of telling user space which driver to load. The kernel defers mapping PCI IDs to module names to user space and we should do the same for DRI drivers. And in fact, that's how it does work today. Nothing uses the dri_library_name attribute, and the attribute is in fact broken. For intel devices, it falls back to the default behaviour of returning the kernel module name as the DRI driver name, which doesn't work for i965 devices. Nobody has ever hit this problem or filed a bug about this. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_sysfs.c | 29 - drivers/gpu/drm/radeon/radeon_drv.c | 12 drivers/gpu/drm/via/via_drv.c |6 -- include/drm/drmP.h |1 - 4 files changed, 0 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 65d72d0..f922c0b 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -118,20 +118,6 @@ void drm_sysfs_destroy(void) class_destroy(drm_class); } -static ssize_t show_dri(struct device *device, struct device_attribute *attr, - char *buf) -{ - struct drm_minor *drm_minor = to_drm_minor(device); - struct drm_device *drm_dev = drm_minor-dev; - if (drm_dev-driver-dri_library_name) - return drm_dev-driver-dri_library_name(drm_dev, buf); - return snprintf(buf, PAGE_SIZE, %s\n, drm_dev-driver-pci_driver.name); -} - -static struct device_attribute device_attrs[] = { - __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), -}; - /** * drm_sysfs_device_release - do nothing * @dev: Linux device @@ -474,7 +460,6 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) int drm_sysfs_device_add(struct drm_minor *minor) { int err; - int i, j; char *minor_str; minor-kdev.parent = minor-dev-pdev-dev; @@ -496,18 +481,8 @@ int drm_sysfs_device_add(struct drm_minor *minor) goto err_out; } - for (i = 0; i ARRAY_SIZE(device_attrs); i++) { - err = device_create_file(minor-kdev, device_attrs[i]); - if (err) - goto err_out_files; - } - return 0; -err_out_files: - if (i 0) - for (j = 0; j i; j++) - device_remove_file(minor-kdev, device_attrs[j]); device_unregister(minor-kdev); err_out: @@ -523,9 +498,5 @@ err_out: */ void drm_sysfs_device_remove(struct drm_minor *minor) { - int i; - - for (i = 0; i ARRAY_SIZE(device_attrs); i++) - device_remove_file(minor-kdev, device_attrs[i]); device_unregister(minor-kdev); } diff --git
Re: [PATCH] Claim PCI device when running in modesetting mode.
Heya, ping again. We're a real driver now, can we please claim the PCI device. Can one of you please add it to your git tree, either current rc or next merge window so we don't drop this on the floor? thanks, Kristian On Tue, Jan 13, 2009 at 9:42 AM, Kristian Høgsberg k...@bitplanet.net wrote: Before this scrolls out of my inbox: any comments? On Sun, Jan 4, 2009 at 4:28 PM, Kristian Høgsberg k...@redhat.com wrote: Under kernel modesetting, we manage the device at all times, regardless of VT switching and X servers, so the only decent thing to do is to claim the PCI device. In that case, we call the suspend/resume hooks directly from the pci driver hooks instead of the current class device detour. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_drv.c | 67 +- drivers/gpu/drm/drm_stub.c | 85 -- drivers/gpu/drm/drm_sysfs.c |8 +++- drivers/gpu/drm/i915/i915_drv.c | 38 + include/drm/drmP.h |2 +- 5 files changed, 119 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index febb517..44bf3ae 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -252,15 +252,19 @@ int drm_lastclose(struct drm_device * dev) int drm_init(struct drm_driver *driver) { struct pci_dev *pdev = NULL; - struct pci_device_id *pid; + const struct pci_device_id *pid; int i; DRM_DEBUG(\n); INIT_LIST_HEAD(driver-device_list); + if (driver-driver_features DRIVER_MODESET) + return pci_register_driver(driver-pci_driver); + + /* If not using KMS, fall back to stealth mode manual scanning. */ for (i = 0; driver-pci_driver.id_table[i].vendor != 0; i++) { - pid = (struct pci_device_id *)driver-pci_driver.id_table[i]; + pid = driver-pci_driver.id_table[i]; /* Loop around setting up a DRM device for each PCI device * matching our ID and device class. If we had the internal @@ -285,64 +289,17 @@ int drm_init(struct drm_driver *driver) EXPORT_SYMBOL(drm_init); -/** - * Called via cleanup_module() at module unload time. - * - * Cleans up all DRM device, calling drm_lastclose(). - * - * \sa drm_init - */ -static void drm_cleanup(struct drm_device * dev) -{ - DRM_DEBUG(\n); - - if (!dev) { - DRM_ERROR(cleanup called no dev\n); - return; - } - - drm_vblank_cleanup(dev); - - drm_lastclose(dev); - - if (drm_core_has_MTRR(dev) drm_core_has_AGP(dev) - dev-agp dev-agp-agp_mtrr = 0) { - int retval; - retval = mtrr_del(dev-agp-agp_mtrr, - dev-agp-agp_info.aper_base, - dev-agp-agp_info.aper_size * 1024 * 1024); - DRM_DEBUG(mtrr_del=%d\n, retval); - } - - if (drm_core_has_AGP(dev) dev-agp) { - drm_free(dev-agp, sizeof(*dev-agp), DRM_MEM_AGPLISTS); - dev-agp = NULL; - } - - if (dev-driver-unload) - dev-driver-unload(dev); - - drm_ht_remove(dev-map_hash); - drm_ctxbitmap_cleanup(dev); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(dev-control); - - if (dev-driver-driver_features DRIVER_GEM) - drm_gem_destroy(dev); - - drm_put_minor(dev-primary); - if (drm_put_dev(dev)) - DRM_ERROR(Cannot unload module\n); -} - void drm_exit(struct drm_driver *driver) { struct drm_device *dev, *tmp; DRM_DEBUG(\n); - list_for_each_entry_safe(dev, tmp, driver-device_list, driver_item) - drm_cleanup(dev); + if (driver-driver_features DRIVER_MODESET) { + pci_unregister_driver(driver-pci_driver); + } else { + list_for_each_entry_safe(dev, tmp, driver-device_list, driver_item) + drm_put_dev(dev); + } DRM_INFO(Module unloaded\n); } diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 5ca132a..e8b2c3f 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -372,6 +372,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, } if (drm_core_check_feature(dev, DRIVER_MODESET)) { + pci_set_drvdata(pdev, dev); ret = drm_get_minor(dev, dev-control, DRM_MINOR_CONTROL); if (ret) goto err_g2; @@ -409,29 +410,7 @@ err_g1: drm_free(dev, sizeof(*dev), DRM_MEM_STUB); return ret; } - -/** - * Put a device minor number. - * - * \param dev device data structure - * \return always zero - * - * Cleans
Re: [PATCH] drm: Drop unused and broken dri_library_name sysfs attribute.
Hey; comments on this? Can we put it in one of the git tree so it doesn't fall through the cracks? It's pretty harmless and could be merged for the 2.6.29 kernel, or we could push it the the next merge window if it's not suitable for the rc phase. Either way, we need to squash this. cheers, Kristian On Mon, Jan 5, 2009 at 4:10 PM, Kristian Høgsberg k...@redhat.com wrote: The kernel shouldn't be in the business of telling user space which driver to load. The kernel defers mapping PCI IDs to module names to user space and we should do the same for DRI drivers. And in fact, that's how it does work today. Nothing uses the dri_library_name attribute, and the attribute is in fact broken. For intel devices, it falls back to the default behaviour of returning the kernel module name as the DRI driver name, which doesn't work for i965 devices. Nobody has ever hit this problem or filed a bug about this. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_sysfs.c | 29 - drivers/gpu/drm/radeon/radeon_drv.c | 12 drivers/gpu/drm/via/via_drv.c |6 -- include/drm/drmP.h |1 - 4 files changed, 0 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 65d72d0..f922c0b 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -118,20 +118,6 @@ void drm_sysfs_destroy(void) class_destroy(drm_class); } -static ssize_t show_dri(struct device *device, struct device_attribute *attr, - char *buf) -{ - struct drm_minor *drm_minor = to_drm_minor(device); - struct drm_device *drm_dev = drm_minor-dev; - if (drm_dev-driver-dri_library_name) - return drm_dev-driver-dri_library_name(drm_dev, buf); - return snprintf(buf, PAGE_SIZE, %s\n, drm_dev-driver-pci_driver.name); -} - -static struct device_attribute device_attrs[] = { - __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), -}; - /** * drm_sysfs_device_release - do nothing * @dev: Linux device @@ -474,7 +460,6 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) int drm_sysfs_device_add(struct drm_minor *minor) { int err; - int i, j; char *minor_str; minor-kdev.parent = minor-dev-pdev-dev; @@ -496,18 +481,8 @@ int drm_sysfs_device_add(struct drm_minor *minor) goto err_out; } - for (i = 0; i ARRAY_SIZE(device_attrs); i++) { - err = device_create_file(minor-kdev, device_attrs[i]); - if (err) - goto err_out_files; - } - return 0; -err_out_files: - if (i 0) - for (j = 0; j i; j++) - device_remove_file(minor-kdev, device_attrs[j]); device_unregister(minor-kdev); err_out: @@ -523,9 +498,5 @@ err_out: */ void drm_sysfs_device_remove(struct drm_minor *minor) { - int i; - - for (i = 0; i ARRAY_SIZE(device_attrs); i++) - device_remove_file(minor-kdev, device_attrs[i]); device_unregister(minor-kdev); } diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 71af746..971f380 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -41,17 +41,6 @@ int radeon_no_wb; MODULE_PARM_DESC(no_wb, Disable AGP writeback for scratch registers); module_param_named(no_wb, radeon_no_wb, int, 0444); -static int dri_library_name(struct drm_device *dev, char *buf) -{ - drm_radeon_private_t *dev_priv = dev-dev_private; - int family = dev_priv-flags RADEON_FAMILY_MASK; - - return snprintf(buf, PAGE_SIZE, %s\n, - (family CHIP_R200) ? radeon : - ((family CHIP_R300) ? r200 : - r300)); -} - static int radeon_suspend(struct drm_device *dev, pm_message_t state) { drm_radeon_private_t *dev_priv = dev-dev_private; @@ -95,7 +84,6 @@ static struct drm_driver driver = { .get_vblank_counter = radeon_get_vblank_counter, .enable_vblank = radeon_enable_vblank, .disable_vblank = radeon_disable_vblank, - .dri_library_name = dri_library_name, .irq_preinstall = radeon_driver_irq_preinstall, .irq_postinstall = radeon_driver_irq_postinstall, .irq_uninstall = radeon_driver_irq_uninstall, diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index 0993b44..bc2f518 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c @@ -28,11 +28,6 @@ #include drm_pciids.h -static int dri_library_name(struct drm_device *dev, char *buf) -{ - return snprintf(buf, PAGE_SIZE, unichrome); -} - static struct pci_device_id pciidlist[] = { viadrv_PCI_IDS }; @@ -52,7 +47,6 @@ static
[PATCH] drm: Drop unused and broken dri_library_name sysfs attribute.
The kernel shouldn't be in the business of telling user space which driver to load. The kernel defers mapping PCI IDs to module names to user space and we should do the same for DRI drivers. And in fact, that's how it does work today. Nothing uses the dri_library_name attribute, and the attribute is in fact broken. For intel devices, it falls back to the default behaviour of returning the kernel module name as the DRI driver name, which doesn't work for i965 devices. Nobody has ever hit this problem or filed a bug about this. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_sysfs.c | 29 - drivers/gpu/drm/radeon/radeon_drv.c | 12 drivers/gpu/drm/via/via_drv.c |6 -- include/drm/drmP.h |1 - 4 files changed, 0 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 65d72d0..f922c0b 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -118,20 +118,6 @@ void drm_sysfs_destroy(void) class_destroy(drm_class); } -static ssize_t show_dri(struct device *device, struct device_attribute *attr, - char *buf) -{ - struct drm_minor *drm_minor = to_drm_minor(device); - struct drm_device *drm_dev = drm_minor-dev; - if (drm_dev-driver-dri_library_name) - return drm_dev-driver-dri_library_name(drm_dev, buf); - return snprintf(buf, PAGE_SIZE, %s\n, drm_dev-driver-pci_driver.name); -} - -static struct device_attribute device_attrs[] = { - __ATTR(dri_library_name, S_IRUGO, show_dri, NULL), -}; - /** * drm_sysfs_device_release - do nothing * @dev: Linux device @@ -474,7 +460,6 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) int drm_sysfs_device_add(struct drm_minor *minor) { int err; - int i, j; char *minor_str; minor-kdev.parent = minor-dev-pdev-dev; @@ -496,18 +481,8 @@ int drm_sysfs_device_add(struct drm_minor *minor) goto err_out; } - for (i = 0; i ARRAY_SIZE(device_attrs); i++) { - err = device_create_file(minor-kdev, device_attrs[i]); - if (err) - goto err_out_files; - } - return 0; -err_out_files: - if (i 0) - for (j = 0; j i; j++) - device_remove_file(minor-kdev, device_attrs[j]); device_unregister(minor-kdev); err_out: @@ -523,9 +498,5 @@ err_out: */ void drm_sysfs_device_remove(struct drm_minor *minor) { - int i; - - for (i = 0; i ARRAY_SIZE(device_attrs); i++) - device_remove_file(minor-kdev, device_attrs[i]); device_unregister(minor-kdev); } diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 71af746..971f380 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -41,17 +41,6 @@ int radeon_no_wb; MODULE_PARM_DESC(no_wb, Disable AGP writeback for scratch registers); module_param_named(no_wb, radeon_no_wb, int, 0444); -static int dri_library_name(struct drm_device *dev, char *buf) -{ - drm_radeon_private_t *dev_priv = dev-dev_private; - int family = dev_priv-flags RADEON_FAMILY_MASK; - - return snprintf(buf, PAGE_SIZE, %s\n, - (family CHIP_R200) ? radeon : - ((family CHIP_R300) ? r200 : - r300)); -} - static int radeon_suspend(struct drm_device *dev, pm_message_t state) { drm_radeon_private_t *dev_priv = dev-dev_private; @@ -95,7 +84,6 @@ static struct drm_driver driver = { .get_vblank_counter = radeon_get_vblank_counter, .enable_vblank = radeon_enable_vblank, .disable_vblank = radeon_disable_vblank, - .dri_library_name = dri_library_name, .irq_preinstall = radeon_driver_irq_preinstall, .irq_postinstall = radeon_driver_irq_postinstall, .irq_uninstall = radeon_driver_irq_uninstall, diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index 0993b44..bc2f518 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c @@ -28,11 +28,6 @@ #include drm_pciids.h -static int dri_library_name(struct drm_device *dev, char *buf) -{ - return snprintf(buf, PAGE_SIZE, unichrome); -} - static struct pci_device_id pciidlist[] = { viadrv_PCI_IDS }; @@ -52,7 +47,6 @@ static struct drm_driver driver = { .irq_uninstall = via_driver_irq_uninstall, .irq_handler = via_driver_irq_handler, .dma_quiescent = via_driver_dma_quiescent, - .dri_library_name = dri_library_name, .reclaim_buffers = drm_core_reclaim_buffers, .reclaim_buffers_locked = NULL, .reclaim_buffers_idlelocked = via_reclaim_buffers_locked, diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 7802c80..63a1bb3 100644
[PATCH] Claim PCI device when running in modesetting mode.
Under kernel modesetting, we manage the device at all times, regardless of VT switching and X servers, so the only decent thing to do is to claim the PCI device. In that case, we call the suspend/resume hooks directly from the pci driver hooks instead of the current class device detour. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_drv.c | 67 +- drivers/gpu/drm/drm_stub.c | 85 -- drivers/gpu/drm/drm_sysfs.c |8 +++- drivers/gpu/drm/i915/i915_drv.c | 38 + include/drm/drmP.h |2 +- 5 files changed, 119 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index febb517..44bf3ae 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -252,15 +252,19 @@ int drm_lastclose(struct drm_device * dev) int drm_init(struct drm_driver *driver) { struct pci_dev *pdev = NULL; - struct pci_device_id *pid; + const struct pci_device_id *pid; int i; DRM_DEBUG(\n); INIT_LIST_HEAD(driver-device_list); + if (driver-driver_features DRIVER_MODESET) + return pci_register_driver(driver-pci_driver); + + /* If not using KMS, fall back to stealth mode manual scanning. */ for (i = 0; driver-pci_driver.id_table[i].vendor != 0; i++) { - pid = (struct pci_device_id *)driver-pci_driver.id_table[i]; + pid = driver-pci_driver.id_table[i]; /* Loop around setting up a DRM device for each PCI device * matching our ID and device class. If we had the internal @@ -285,64 +289,17 @@ int drm_init(struct drm_driver *driver) EXPORT_SYMBOL(drm_init); -/** - * Called via cleanup_module() at module unload time. - * - * Cleans up all DRM device, calling drm_lastclose(). - * - * \sa drm_init - */ -static void drm_cleanup(struct drm_device * dev) -{ - DRM_DEBUG(\n); - - if (!dev) { - DRM_ERROR(cleanup called no dev\n); - return; - } - - drm_vblank_cleanup(dev); - - drm_lastclose(dev); - - if (drm_core_has_MTRR(dev) drm_core_has_AGP(dev) - dev-agp dev-agp-agp_mtrr = 0) { - int retval; - retval = mtrr_del(dev-agp-agp_mtrr, - dev-agp-agp_info.aper_base, - dev-agp-agp_info.aper_size * 1024 * 1024); - DRM_DEBUG(mtrr_del=%d\n, retval); - } - - if (drm_core_has_AGP(dev) dev-agp) { - drm_free(dev-agp, sizeof(*dev-agp), DRM_MEM_AGPLISTS); - dev-agp = NULL; - } - - if (dev-driver-unload) - dev-driver-unload(dev); - - drm_ht_remove(dev-map_hash); - drm_ctxbitmap_cleanup(dev); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(dev-control); - - if (dev-driver-driver_features DRIVER_GEM) - drm_gem_destroy(dev); - - drm_put_minor(dev-primary); - if (drm_put_dev(dev)) - DRM_ERROR(Cannot unload module\n); -} - void drm_exit(struct drm_driver *driver) { struct drm_device *dev, *tmp; DRM_DEBUG(\n); - list_for_each_entry_safe(dev, tmp, driver-device_list, driver_item) - drm_cleanup(dev); + if (driver-driver_features DRIVER_MODESET) { + pci_unregister_driver(driver-pci_driver); + } else { + list_for_each_entry_safe(dev, tmp, driver-device_list, driver_item) + drm_put_dev(dev); + } DRM_INFO(Module unloaded\n); } diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 5ca132a..e8b2c3f 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -372,6 +372,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, } if (drm_core_check_feature(dev, DRIVER_MODESET)) { + pci_set_drvdata(pdev, dev); ret = drm_get_minor(dev, dev-control, DRM_MINOR_CONTROL); if (ret) goto err_g2; @@ -409,29 +410,7 @@ err_g1: drm_free(dev, sizeof(*dev), DRM_MEM_STUB); return ret; } - -/** - * Put a device minor number. - * - * \param dev device data structure - * \return always zero - * - * Cleans up the proc resources. If it is the last minor then release the foreign - * drm data, otherwise unregisters the drm data, frees the dev list and - * unregisters the character device. - */ -int drm_put_dev(struct drm_device * dev) -{ - DRM_DEBUG(release primary %s\n, dev-driver-pci_driver.name); - - if (dev-devname) { - drm_free(dev-devname, strlen(dev-devname) + 1, -DRM_MEM_DRIVER); - dev-devname = NULL; - } - drm_free(dev, sizeof(*dev), DRM_MEM_STUB
[PATCH] Claim PCI device when running in modesetting mode.
Under kernel modesetting, we manage the device at all times, regardless of VT switching and X servers, so the only decent thing to do is to claim the PCI device. In that case, we call the suspend/resume hooks directly from the pci driver hooks instead of the current class device detour. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_drv.c | 67 +- drivers/gpu/drm/drm_stub.c | 85 -- drivers/gpu/drm/drm_sysfs.c |8 +++- drivers/gpu/drm/i915/i915_drv.c | 38 + include/drm/drmP.h |2 +- 5 files changed, 119 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index febb517..44bf3ae 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -252,15 +252,19 @@ int drm_lastclose(struct drm_device * dev) int drm_init(struct drm_driver *driver) { struct pci_dev *pdev = NULL; - struct pci_device_id *pid; + const struct pci_device_id *pid; int i; DRM_DEBUG(\n); INIT_LIST_HEAD(driver-device_list); + if (driver-driver_features DRIVER_MODESET) + return pci_register_driver(driver-pci_driver); + + /* If not using KMS, fall back to stealth mode manual scanning. */ for (i = 0; driver-pci_driver.id_table[i].vendor != 0; i++) { - pid = (struct pci_device_id *)driver-pci_driver.id_table[i]; + pid = driver-pci_driver.id_table[i]; /* Loop around setting up a DRM device for each PCI device * matching our ID and device class. If we had the internal @@ -285,64 +289,17 @@ int drm_init(struct drm_driver *driver) EXPORT_SYMBOL(drm_init); -/** - * Called via cleanup_module() at module unload time. - * - * Cleans up all DRM device, calling drm_lastclose(). - * - * \sa drm_init - */ -static void drm_cleanup(struct drm_device * dev) -{ - DRM_DEBUG(\n); - - if (!dev) { - DRM_ERROR(cleanup called no dev\n); - return; - } - - drm_vblank_cleanup(dev); - - drm_lastclose(dev); - - if (drm_core_has_MTRR(dev) drm_core_has_AGP(dev) - dev-agp dev-agp-agp_mtrr = 0) { - int retval; - retval = mtrr_del(dev-agp-agp_mtrr, - dev-agp-agp_info.aper_base, - dev-agp-agp_info.aper_size * 1024 * 1024); - DRM_DEBUG(mtrr_del=%d\n, retval); - } - - if (drm_core_has_AGP(dev) dev-agp) { - drm_free(dev-agp, sizeof(*dev-agp), DRM_MEM_AGPLISTS); - dev-agp = NULL; - } - - if (dev-driver-unload) - dev-driver-unload(dev); - - drm_ht_remove(dev-map_hash); - drm_ctxbitmap_cleanup(dev); - - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(dev-control); - - if (dev-driver-driver_features DRIVER_GEM) - drm_gem_destroy(dev); - - drm_put_minor(dev-primary); - if (drm_put_dev(dev)) - DRM_ERROR(Cannot unload module\n); -} - void drm_exit(struct drm_driver *driver) { struct drm_device *dev, *tmp; DRM_DEBUG(\n); - list_for_each_entry_safe(dev, tmp, driver-device_list, driver_item) - drm_cleanup(dev); + if (driver-driver_features DRIVER_MODESET) { + pci_unregister_driver(driver-pci_driver); + } else { + list_for_each_entry_safe(dev, tmp, driver-device_list, driver_item) + drm_put_dev(dev); + } DRM_INFO(Module unloaded\n); } diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 5ca132a..e8b2c3f 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -372,6 +372,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, } if (drm_core_check_feature(dev, DRIVER_MODESET)) { + pci_set_drvdata(pdev, dev); ret = drm_get_minor(dev, dev-control, DRM_MINOR_CONTROL); if (ret) goto err_g2; @@ -409,29 +410,7 @@ err_g1: drm_free(dev, sizeof(*dev), DRM_MEM_STUB); return ret; } - -/** - * Put a device minor number. - * - * \param dev device data structure - * \return always zero - * - * Cleans up the proc resources. If it is the last minor then release the foreign - * drm data, otherwise unregisters the drm data, frees the dev list and - * unregisters the character device. - */ -int drm_put_dev(struct drm_device * dev) -{ - DRM_DEBUG(release primary %s\n, dev-driver-pci_driver.name); - - if (dev-devname) { - drm_free(dev-devname, strlen(dev-devname) + 1, -DRM_MEM_DRIVER); - dev-devname = NULL; - } - drm_free(dev, sizeof(*dev), DRM_MEM_STUB
Re: [PATCH] Pin cursor bo and unpin old bo when setting cursor.
Hey Eric, I didn't see this one go into the drm-intel-next tree. I forgot to pass -n to format-patch so it's easier to overlook it, I guess, but we also need to pin the cursor bo when we set the cursor as we do for the fb bo when setting the mode. Like the pin-fb-bo patch, this one is a semantic change that we should get into the tree before we merge it for 2.6.29. cheers, Kristian On Thu, Dec 18, 2008 at 4:14 AM, Kristian Høgsberg k...@redhat.com wrote: We also didn't track the cursor bo before and would leak a reference when the cursor image was change. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/i915/intel_display.c | 29 + drivers/gpu/drm/i915/intel_drv.h |1 + 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8e5a242..ec92551 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -986,19 +986,17 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; uint32_t temp; size_t addr; + int ret; DRM_DEBUG(\n); /* if we want to turn off the cursor ignore width and height */ if (!handle) { DRM_DEBUG(cursor off\n); - /* turn of the cursor */ - temp = 0; - temp |= CURSOR_MODE_DISABLE; - - I915_WRITE(control, temp); - I915_WRITE(base, 0); - return 0; + temp = CURSOR_MODE_DISABLE; + addr = 0; + bo = NULL; + goto finish; } /* Currently we only support 64x64 cursors */ @@ -1025,15 +1023,30 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, addr = obj_priv-gtt_offset; } - intel_crtc-cursor_addr = addr; + ret = i915_gem_object_pin(bo, PAGE_SIZE); + if (ret) { + DRM_ERROR(failed to pin cursor bo\n); + drm_gem_object_unreference(bo); + return ret; + } + temp = 0; /* set the pipe for the cursor */ temp |= (pipe 28); temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + finish: I915_WRITE(control, temp); I915_WRITE(base, addr); + if (intel_crtc-cursor_bo) { + i915_gem_object_unpin(intel_crtc-cursor_bo); + drm_gem_object_unreference(intel_crtc-cursor_bo); + } + + intel_crtc-cursor_addr = addr; + intel_crtc-cursor_bo = bo; + return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 407edd5..94981ee 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -88,6 +88,7 @@ struct intel_crtc { struct drm_crtc base; int pipe; int plane; + struct drm_gem_object *cursor_bo; uint32_t cursor_addr; u8 lut_r[256], lut_g[256], lut_b[256]; int dpms_mode; -- 1.6.0.5 -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel -- -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] Pin cursor bo and unpin old bo when setting cursor.
We also didn't track the cursor bo before and would leak a reference when the cursor image was change. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/i915/intel_display.c | 29 + drivers/gpu/drm/i915/intel_drv.h |1 + 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8e5a242..ec92551 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -986,19 +986,17 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, uint32_t base = (pipe == 0) ? CURABASE : CURBBASE; uint32_t temp; size_t addr; + int ret; DRM_DEBUG(\n); /* if we want to turn off the cursor ignore width and height */ if (!handle) { DRM_DEBUG(cursor off\n); - /* turn of the cursor */ - temp = 0; - temp |= CURSOR_MODE_DISABLE; - - I915_WRITE(control, temp); - I915_WRITE(base, 0); - return 0; + temp = CURSOR_MODE_DISABLE; + addr = 0; + bo = NULL; + goto finish; } /* Currently we only support 64x64 cursors */ @@ -1025,15 +1023,30 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, addr = obj_priv-gtt_offset; } - intel_crtc-cursor_addr = addr; + ret = i915_gem_object_pin(bo, PAGE_SIZE); + if (ret) { + DRM_ERROR(failed to pin cursor bo\n); + drm_gem_object_unreference(bo); + return ret; + } + temp = 0; /* set the pipe for the cursor */ temp |= (pipe 28); temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + finish: I915_WRITE(control, temp); I915_WRITE(base, addr); + if (intel_crtc-cursor_bo) { + i915_gem_object_unpin(intel_crtc-cursor_bo); + drm_gem_object_unreference(intel_crtc-cursor_bo); + } + + intel_crtc-cursor_addr = addr; + intel_crtc-cursor_bo = bo; + return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 407edd5..94981ee 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -88,6 +88,7 @@ struct intel_crtc { struct drm_crtc base; int pipe; int plane; + struct drm_gem_object *cursor_bo; uint32_t cursor_addr; u8 lut_r[256], lut_g[256], lut_b[256]; int dpms_mode; -- 1.6.0.5 -- SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada. The future of the web can't happen without you. Join us at MIX09 to help pave the way to the Next Web now. Learn more and register at http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/ -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel
[PATCH] Drop DRM_IOCTL_MODE_REPLACEFB, add+remove works just as well.
The replace fb ioctl replaces the backing buffer object for a modesetting framebuffer object. This can be acheived by just creating a new framebuffer backed by the new buffer object, setting that for the crtcs in question and then removing the old framebuffer object. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_crtc.c | 40 -- drivers/gpu/drm/drm_drv.c|1 - drivers/gpu/drm/i915/intel_display.c | 31 -- include/drm/drm.h|1 - include/drm/drm_crtc.h |1 - 5 files changed, 0 insertions(+), 74 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 2e88024..71a1344 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -2313,46 +2313,6 @@ out: return ret; } - -int drm_mode_replacefb(struct drm_device *dev, - void *data, struct drm_file *file_priv) -{ - struct drm_mode_fb_cmd *r = data; - struct drm_mode_object *obj; - struct drm_framebuffer *fb; - int found = 0; - struct drm_framebuffer *fbl = NULL; - int ret = 0; - - /* right replace the current bo attached to this fb with a new bo */ - mutex_lock(dev-mode_config.mutex); - obj = drm_mode_object_find(dev, r-buffer_id, DRM_MODE_OBJECT_FB); - if (!obj) { - ret = -EINVAL; - goto out; - } - fb = obj_to_fb(obj); - - list_for_each_entry(fbl, file_priv-fbs, filp_head) - if (fb == fbl) - found = 1; - - if (!found) { - DRM_ERROR(tried to replace an fb we didn't own\n); - ret = -EINVAL; - goto out; - } - - if (dev-mode_config.funcs-resize_fb) - ret = dev-mode_config.funcs-resize_fb(dev, file_priv, fb, r); - else - ret = -EINVAL; -out: - mutex_unlock(dev-mode_config.mutex); - return ret; - -} - int drm_mode_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder) { diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 0b9f316..dea29ad 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -142,7 +142,6 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_REPLACEFB, drm_mode_replacefb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER), diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 96c2da5..5689e44 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1528,38 +1528,7 @@ intel_user_framebuffer_create(struct drm_device *dev, return fb; } -static int intel_insert_new_fb(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_framebuffer *fb, - struct drm_mode_fb_cmd *mode_cmd) -{ - struct intel_framebuffer *intel_fb; - struct drm_gem_object *obj; - struct drm_crtc *crtc; - - intel_fb = to_intel_framebuffer(fb); - - obj = drm_gem_object_lookup(dev, file_priv, mode_cmd-handle); - - if (!obj) - return -EINVAL; - - intel_fb-obj = obj; - drm_gem_object_unreference(intel_fb-obj); - drm_helper_mode_fill_fb_struct(fb, mode_cmd); - mutex_unlock(dev-struct_mutex); - - list_for_each_entry(crtc, dev-mode_config.crtc_list, head) { - if (crtc-fb == fb) { - struct drm_crtc_helper_funcs *crtc_funcs = crtc-helper_private; - crtc_funcs-mode_set_base(crtc, crtc-x, crtc-y); - } - } - return 0; -} - static const struct drm_mode_config_funcs intel_mode_funcs = { - .resize_fb = intel_insert_new_fb, .fb_create = intel_user_framebuffer_create, .fb_changed = intelfb_probe, }; diff --git a/include/drm/drm.h b/include/drm/drm.h index 76ce6fe..32e5096 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -687,7 +687,6 @@ struct drm_gem_open { #define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_RMFBDRM_IOWR(0xAF, unsigned int) -#define DRM_IOCTL_MODE_REPLACEFB
[PATCH] Pin new and unpin old buffer when setting a mode.
This removes the requirement for user space to pin a buffer before setting a mode that is backed by the pixels from that buffer. Signed-off-by: Kristian Høgsberg k...@redhat.com --- drivers/gpu/drm/drm_crtc_helper.c| 20 ++- drivers/gpu/drm/i915/intel_display.c | 44 +++-- include/drm/drm_crtc_helper.h|9 -- 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index f914044..3082841 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -432,7 +432,8 @@ static void drm_setup_crtcs(struct drm_device *dev) */ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, - int x, int y) + int x, int y, + struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc-dev; struct drm_display_mode *adjusted_mode, saved_mode; @@ -462,7 +463,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, if (drm_mode_equal(saved_mode, crtc-mode)) { if (saved_x != crtc-x || saved_y != crtc-y) { - crtc_funcs-mode_set_base(crtc, crtc-x, crtc-y); + crtc_funcs-mode_set_base(crtc, crtc-x, crtc-y, + old_fb); goto done; } } @@ -501,7 +503,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, /* Set up the DPLL and any encoders state that needs to adjust or depend * on the DPLL. */ - crtc_funcs-mode_set(crtc, mode, adjusted_mode, x, y); + crtc_funcs-mode_set(crtc, mode, adjusted_mode, x, y, old_fb); list_for_each_entry(encoder, dev-mode_config.encoder_list, head) { @@ -564,6 +566,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) struct drm_device *dev; struct drm_crtc **save_crtcs, *new_crtc; struct drm_encoder **save_encoders, *new_encoder; + struct drm_framebuffer *old_fb; bool save_enabled; bool changed = false; bool flip_or_move = false; @@ -684,13 +687,15 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) changed = true; if (changed) { + old_fb = set-crtc-fb; set-crtc-fb = set-fb; set-crtc-enabled = (set-mode != NULL); if (set-mode != NULL) { DRM_DEBUG(attempting to set mode from userspace\n); drm_mode_debug_printmodeline(set-mode); if (!drm_crtc_helper_set_mode(set-crtc, set-mode, - set-x, set-y)) { + set-x, set-y, + old_fb)) { ret = -EINVAL; goto fail_set_mode; } @@ -701,9 +706,10 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set) } drm_helper_disable_unused_functions(dev); } else if (flip_or_move) { + old_fb = set-crtc-fb; if (set-crtc-fb != set-fb) set-crtc-fb = set-fb; - crtc_funcs-mode_set_base(set-crtc, set-x, set-y); + crtc_funcs-mode_set_base(set-crtc, set-x, set-y, old_fb); } kfree(save_encoders); @@ -811,8 +817,8 @@ int drm_helper_resume_force_mode(struct drm_device *dev) if (!crtc-enabled) continue; - ret = drm_crtc_helper_set_mode(crtc, crtc-mode, crtc-x, - crtc-y); + ret = drm_crtc_helper_set_mode(crtc, crtc-mode, + crtc-x, crtc-y, crtc-fb); if (ret == false) DRM_ERROR(failed to set mode on crtc %p\n, crtc); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5689e44..8e5a242 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -344,7 +344,8 @@ intel_wait_for_vblank(struct drm_device *dev) } void -intel_pipe_set_base(struct drm_crtc *crtc, int x, int y) +intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc-dev; struct drm_i915_private *dev_priv = dev-dev_private; @@ -359,7 +360,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y) int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR; - u32 dspcntr; + u32
Re: [PATCH] [drm/i915] Move legacy breadcrumb out of the reserved status page area
On Fri, Nov 7, 2008 at 8:44 PM, Keith Packard [EMAIL PROTECTED] wrote: Addresses in the hardware status page below index 0x20 are reserved for use by the hardware. The legacy breadcrumb was sitting at index 5. Move it to index 0x21, and make sure everyone uses the defined value instead of hard-coded constants. Just remove it completely? I don't think anything really use it. Kristian - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ -- ___ Dri-devel mailing list Dri-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/dri-devel