diff options
Diffstat (limited to 'libdrm')
| -rw-r--r-- | libdrm/Makefile.am | 4 | ||||
| -rw-r--r-- | libdrm/dri_bufmgr.h | 178 | ||||
| -rw-r--r-- | libdrm/intel/Makefile.am | 7 | ||||
| -rw-r--r-- | libdrm/intel/intel_bufmgr.c (renamed from libdrm/dri_bufmgr.c) | 69 | ||||
| -rw-r--r-- | libdrm/intel/intel_bufmgr.h | 133 | ||||
| -rw-r--r-- | libdrm/intel/intel_bufmgr_fake.c | 304 | ||||
| -rw-r--r-- | libdrm/intel/intel_bufmgr_gem.c | 161 | ||||
| -rw-r--r-- | libdrm/intel/intel_bufmgr_priv.h | 165 | ||||
| -rw-r--r-- | libdrm/xf86drm.c | 27 | 
9 files changed, 625 insertions, 423 deletions
| diff --git a/libdrm/Makefile.am b/libdrm/Makefile.am index c6d66732..532ca138 100644 --- a/libdrm/Makefile.am +++ b/libdrm/Makefile.am @@ -26,10 +26,10 @@ libdrm_la_LDFLAGS = -version-number 2:3:0 -no-undefined  AM_CFLAGS = -I$(top_srcdir)/shared-core  libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \ -	xf86drmMode.c dri_bufmgr.c libdrm_lists.h +	xf86drmMode.c  libdrm_la_LIBADD = intel/libdrm_intel.la  libdrmincludedir = ${includedir} -libdrminclude_HEADERS = xf86drm.h xf86drmMode.h dri_bufmgr.h +libdrminclude_HEADERS = xf86drm.h xf86drmMode.h  EXTRA_DIST = ChangeLog TODO diff --git a/libdrm/dri_bufmgr.h b/libdrm/dri_bufmgr.h deleted file mode 100644 index 2005bdc6..00000000 --- a/libdrm/dri_bufmgr.h +++ /dev/null @@ -1,178 +0,0 @@ -/************************************************************************** - *  - * Copyright © 2007 Intel Corporation - * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA - * 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, sub license, 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 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 NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS 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. - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - *  - *  - **************************************************************************/ -/* - * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com> - *          Keith Whitwell <keithw-at-tungstengraphics-dot-com> - *	    Eric Anholt <eric@anholt.net> - */ - -#ifndef _DRI_BUFMGR_H_ -#define _DRI_BUFMGR_H_ -#include <xf86drm.h> - -typedef struct _dri_bufmgr dri_bufmgr; -typedef struct _dri_bo dri_bo; - -struct _dri_bo { -   /** -    * Size in bytes of the buffer object. -    * -    * The size may be larger than the size originally requested for the -    * allocation, such as being aligned to page size. -    */ -   unsigned long size; -   /** -    * Card virtual address (offset from the beginning of the aperture) for the -    * object.  Only valid while validated. -    */ -   unsigned long offset; -   /** -    * Virtual address for accessing the buffer data.  Only valid while mapped. -    */ -   void *virtual; -   /** Buffer manager context associated with this buffer object */ -   dri_bufmgr *bufmgr; -   /** -    * MM-specific handle for accessing object -    */ -   int handle; -}; - -/** - * Context for a buffer manager instance. - * - * Contains public methods followed by private storage for the buffer manager. - */ -struct _dri_bufmgr { -   /** -    * Allocate a buffer object. -    * -    * Buffer objects are not necessarily initially mapped into CPU virtual -    * address space or graphics device aperture.  They must be mapped using -    * bo_map() to be used by the CPU, and validated for use using bo_validate() -    * to be used from the graphics device. -    */ -   dri_bo *(*bo_alloc)(dri_bufmgr *bufmgr_ctx, const char *name, -		       unsigned long size, unsigned int alignment); - -   /** Takes a reference on a buffer object */ -   void (*bo_reference)(dri_bo *bo); - -   /** -    * Releases a reference on a buffer object, freeing the data if -    * rerefences remain. -    */ -   void (*bo_unreference)(dri_bo *bo); - -   /** -    * Maps the buffer into userspace. -    * -    * This function will block waiting for any existing execution on the -    * buffer to complete, first.  The resulting mapping is available at -    * buf->virtual. -    */ -   int (*bo_map)(dri_bo *buf, int write_enable); - -   /** Reduces the refcount on the userspace mapping of the buffer object. */ -   int (*bo_unmap)(dri_bo *buf); - -   /** -    * Write data into an object. -    * -    * This is an optional function, if missing, -    * dri_bo will map/memcpy/unmap. -    */ -   int (*bo_subdata) (dri_bo *buf, unsigned long offset, -		      unsigned long size, const void *data); - -   /** -    * Read data from an object -    * -    * This is an optional function, if missing, -    * dri_bo will map/memcpy/unmap. -    */ -   int (*bo_get_subdata) (dri_bo *bo, unsigned long offset, -			  unsigned long size, void *data); - -   /** -    * Waits for rendering to an object by the GPU to have completed. -    * -    * This is not required for any access to the BO by bo_map, bo_subdata, etc. -    * It is merely a way for the driver to implement glFinish. -    */ -   void (*bo_wait_rendering) (dri_bo *bo); - -   /** -    * Tears down the buffer manager instance. -    */ -   void (*destroy)(dri_bufmgr *bufmgr); - -   /** -    * Processes the relocations, either in userland or by converting the list -    * for use in batchbuffer submission. -    * -    * Kernel-based implementations will return a pointer to the arguments -    * to be handed with batchbuffer submission to the kernel.  The userland -    * implementation performs the buffer validation and emits relocations -    * into them the appopriate order. -    * -    * \param batch_buf buffer at the root of the tree of relocations -    * \return argument to be completed and passed to the execbuffers ioctl -    *   (if any). -    */ -   void *(*process_relocs)(dri_bo *batch_buf); - -   void (*post_submit)(dri_bo *batch_buf); - -   int (*check_aperture_space)(dri_bo **bo_array, int count); -   int debug; /**< Enables verbose debugging printouts */ -}; - -dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, -		     unsigned int alignment); -void dri_bo_reference(dri_bo *bo); -void dri_bo_unreference(dri_bo *bo); -int dri_bo_map(dri_bo *buf, int write_enable); -int dri_bo_unmap(dri_bo *buf); - -int dri_bo_subdata(dri_bo *bo, unsigned long offset, -		   unsigned long size, const void *data); -int dri_bo_get_subdata(dri_bo *bo, unsigned long offset, -		       unsigned long size, void *data); -void dri_bo_wait_rendering(dri_bo *bo); - -void dri_bufmgr_set_debug(dri_bufmgr *bufmgr, int enable_debug); -void dri_bufmgr_destroy(dri_bufmgr *bufmgr); - -void *dri_process_relocs(dri_bo *batch_buf); -void dri_post_process_relocs(dri_bo *batch_buf); -void dri_post_submit(dri_bo *batch_buf); -int dri_bufmgr_check_aperture_space(dri_bo **bo_array, int count); - -#endif diff --git a/libdrm/intel/Makefile.am b/libdrm/intel/Makefile.am index 31a8512a..607c4765 100644 --- a/libdrm/intel/Makefile.am +++ b/libdrm/intel/Makefile.am @@ -25,11 +25,16 @@  AM_CFLAGS = \  	$(WARN_CFLAGS) \  	-I$(top_srcdir)/libdrm \ +	-I$(top_srcdir)/libdrm/intel \  	-I$(top_srcdir)/shared-core -noinst_LTLIBRARIES = libdrm_intel.la +libdrm_intel_la_LTLIBRARIES = libdrm_intel.la +libdrm_intel_ladir = $(libdir) +libdrm_intel_la_LDFLAGS = -version-number 1:0:0 -no-undefined  libdrm_intel_la_SOURCES = \ +	intel_bufmgr.c \ +	intel_bufmgr_priv.h \  	intel_bufmgr_fake.c \  	intel_bufmgr_gem.c \  	mm.c \ diff --git a/libdrm/dri_bufmgr.c b/libdrm/intel/intel_bufmgr.c index a6eda3bd..fc7284b5 100644 --- a/libdrm/dri_bufmgr.c +++ b/libdrm/intel/intel_bufmgr.c @@ -25,10 +25,19 @@   *   */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +  #include <string.h>  #include <stdlib.h> +#include <stdint.h>  #include <assert.h> -#include "dri_bufmgr.h" +#include <errno.h> +#include <drm.h> +#include <i915_drm.h> +#include "intel_bufmgr.h" +#include "intel_bufmgr_priv.h"  /** @file dri_bufmgr.c   * @@ -118,14 +127,12 @@ dri_bufmgr_destroy(dri_bufmgr *bufmgr)     bufmgr->destroy(bufmgr);  } -void *dri_process_relocs(dri_bo *batch_buf) -{ -   return batch_buf->bufmgr->process_relocs(batch_buf); -} - -void dri_post_submit(dri_bo *batch_buf) +int +dri_bo_exec(dri_bo *bo, int used, +	    drm_clip_rect_t *cliprects, int num_cliprects, +	    int DR4)  { -   batch_buf->bufmgr->post_submit(batch_buf); +   return bo->bufmgr->bo_exec(bo, used, cliprects, num_cliprects, DR4);  }  void @@ -139,3 +146,49 @@ dri_bufmgr_check_aperture_space(dri_bo **bo_array, int count)  {  	return bo_array[0]->bufmgr->check_aperture_space(bo_array, count);  } + +int +dri_bo_flink(dri_bo *bo, uint32_t *name) +{ +    if (bo->bufmgr->bo_flink) +	return bo->bufmgr->bo_flink(bo, name); + +    return -ENODEV; +} + +int +dri_bo_emit_reloc(dri_bo *reloc_buf, +		  uint32_t read_domains, uint32_t write_domain, +		  uint32_t delta, uint32_t offset, dri_bo *target_buf) +{ +    return reloc_buf->bufmgr->bo_emit_reloc(reloc_buf, +					    read_domains, write_domain, +					    delta, offset, target_buf); +} + +int +dri_bo_pin(dri_bo *bo, uint32_t alignment) +{ +    if (bo->bufmgr->bo_pin) +	return bo->bufmgr->bo_pin(bo, alignment); + +    return -ENODEV; +} + +int +dri_bo_unpin(dri_bo *bo) +{ +    if (bo->bufmgr->bo_unpin) +	return bo->bufmgr->bo_unpin(bo); + +    return -ENODEV; +} + +int dri_bo_set_tiling(dri_bo *bo, uint32_t *tiling_mode) +{ +    if (bo->bufmgr->bo_set_tiling) +	return bo->bufmgr->bo_set_tiling(bo, tiling_mode); + +    *tiling_mode = I915_TILING_NONE; +    return 0; +} diff --git a/libdrm/intel/intel_bufmgr.h b/libdrm/intel/intel_bufmgr.h index 4d335210..c44d596b 100644 --- a/libdrm/intel/intel_bufmgr.h +++ b/libdrm/intel/intel_bufmgr.h @@ -31,65 +31,64 @@   * Public definitions of Intel-specific bufmgr functions.   */ -#ifndef INTEL_BUFMGR_GEM_H -#define INTEL_BUFMGR_GEM_H +#ifndef INTEL_BUFMGR_H +#define INTEL_BUFMGR_H -#include "dri_bufmgr.h" +#include <stdint.h> -/** - * Intel-specific bufmgr bits that follow immediately after the - * generic bufmgr structure. - */ -struct intel_bufmgr { -    /** -     * Add relocation entry in reloc_buf, which will be updated with the -     * target buffer's real offset on on command submission. -     * -     * Relocations remain in place for the lifetime of the buffer object. -     * -     * \param reloc_buf Buffer to write the relocation into. -     * \param read_domains GEM read domains which the buffer will be read into -     *	      by the command that this relocation is part of. -     * \param write_domains GEM read domains which the buffer will be dirtied -     *	      in by the command that this relocation is part of. -     * \param delta Constant value to be added to the relocation target's -     *	       offset. -     * \param offset Byte offset within batch_buf of the relocated pointer. -     * \param target Buffer whose offset should be written into the relocation -     *	     entry. -     */ -    int (*emit_reloc)(dri_bo *reloc_buf, -		      uint32_t read_domains, uint32_t write_domain, -		      uint32_t delta, uint32_t offset, dri_bo *target); +typedef struct _dri_bufmgr dri_bufmgr; +typedef struct _dri_bo dri_bo; + +struct _dri_bo {      /** -     * Pin a buffer to the aperture and fix the offset until unpinned +     * Size in bytes of the buffer object.       * -     * \param buf Buffer to pin -     * \param alignment Required alignment for aperture, in bytes +     * The size may be larger than the size originally requested for the +     * allocation, such as being aligned to page size.       */ -    int (*pin) (dri_bo *buf, uint32_t alignment); +    unsigned long size;      /** -     * Unpin a buffer from the aperture, allowing it to be removed -     * -     * \param buf Buffer to unpin +     * Card virtual address (offset from the beginning of the aperture) for the +     * object.  Only valid while validated.       */ -    int (*unpin) (dri_bo *buf); +    unsigned long offset;      /** -     * Ask that the buffer be placed in tiling mode -     * -     * \param buf Buffer to set tiling mode for -     * \param tiling_mode desired, and returned tiling mode +     * Virtual address for accessing the buffer data.  Only valid while mapped.       */ -    int (*set_tiling) (dri_bo *bo, uint32_t *tiling_mode); -    /** -     * Create a visible name for a buffer which can be used by other apps -     * -     * \param buf Buffer to create a name for -     * \param name Returned name -     */ -    int (*flink) (dri_bo *buf, uint32_t *name); +    void *virtual; + +    /** Buffer manager context associated with this buffer object */ +    dri_bufmgr *bufmgr;  }; +dri_bo *dri_bo_alloc(dri_bufmgr *bufmgr, const char *name, unsigned long size, +		     unsigned int alignment); +void dri_bo_reference(dri_bo *bo); +void dri_bo_unreference(dri_bo *bo); +int dri_bo_map(dri_bo *buf, int write_enable); +int dri_bo_unmap(dri_bo *buf); + +int dri_bo_subdata(dri_bo *bo, unsigned long offset, +		   unsigned long size, const void *data); +int dri_bo_get_subdata(dri_bo *bo, unsigned long offset, +		       unsigned long size, void *data); +void dri_bo_wait_rendering(dri_bo *bo); + +void dri_bufmgr_set_debug(dri_bufmgr *bufmgr, int enable_debug); +void dri_bufmgr_destroy(dri_bufmgr *bufmgr); +int dri_bo_exec(dri_bo *bo, int used, +		drm_clip_rect_t *cliprects, int num_cliprects, +		int DR4); +int dri_bufmgr_check_aperture_space(dri_bo **bo_array, int count); + +int dri_bo_emit_reloc(dri_bo *reloc_buf, +		      uint32_t read_domains, uint32_t write_domain, +		      uint32_t delta, uint32_t offset, dri_bo *target_buf); +int dri_bo_pin(dri_bo *buf, uint32_t alignment); +int dri_bo_unpin(dri_bo *buf); +int dri_bo_set_tiling(dri_bo *buf, uint32_t *tiling_mode); +int dri_bo_flink(dri_bo *buf, uint32_t *name); +  /* intel_bufmgr_gem.c */  dri_bufmgr *intel_bufmgr_gem_init(int fd, int batch_size);  dri_bo *intel_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name, @@ -97,34 +96,32 @@ dri_bo *intel_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,  void intel_bufmgr_gem_enable_reuse(dri_bufmgr *bufmgr);  /* intel_bufmgr_fake.c */ -dri_bufmgr *intel_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, +dri_bufmgr *intel_bufmgr_fake_init(int fd, +				   unsigned long low_offset, void *low_virtual,  				   unsigned long size, -				   unsigned int (*fence_emit)(void *private), -				   int (*fence_wait)(void *private, -						     unsigned int cookie), -				   void *driver_priv); +				   volatile unsigned int *last_dispatch); +void intel_bufmgr_fake_set_last_dispatch(dri_bufmgr *bufmgr, +					 volatile unsigned int *last_dispatch); +void intel_bufmgr_fake_set_exec_callback(dri_bufmgr *bufmgr, +					 int (*exec)(dri_bo *bo, +						     unsigned int used, +						     void *priv), +					 void *priv); +void intel_bufmgr_fake_set_fence_callback(dri_bufmgr *bufmgr, +					  unsigned int (*emit)(void *priv), +					  void (*wait)(unsigned int fence, +						       void *priv), +					  void *priv);  dri_bo *intel_bo_fake_alloc_static(dri_bufmgr *bufmgr, const char *name,  				   unsigned long offset, unsigned long size,  				   void *virtual); - -void intel_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr);  void intel_bo_fake_disable_backing_store(dri_bo *bo,  					 void (*invalidate_cb)(dri_bo *bo,  							       void *ptr),  					 void *ptr); -void intel_bufmgr_fake_evict_all(dri_bufmgr *bufmgr); - -int intel_bo_emit_reloc(dri_bo *reloc_buf, -			uint32_t read_domains, uint32_t write_domain, -			uint32_t delta, uint32_t offset, dri_bo *target_buf); - -int intel_bo_pin(dri_bo *buf, uint32_t alignment); - -int intel_bo_unpin(dri_bo *buf); -int intel_bo_set_tiling(dri_bo *buf, uint32_t *tiling_mode); - -int intel_bo_flink(dri_bo *buf, uint32_t *name); +void intel_bufmgr_fake_contended_lock_take(dri_bufmgr *bufmgr); +void intel_bufmgr_fake_evict_all(dri_bufmgr *bufmgr); -#endif /* INTEL_BUFMGR_GEM_H */ +#endif /* INTEL_BUFMGR_H */ diff --git a/libdrm/intel/intel_bufmgr_fake.c b/libdrm/intel/intel_bufmgr_fake.c index 15da398f..c88e1cb0 100644 --- a/libdrm/intel/intel_bufmgr_fake.c +++ b/libdrm/intel/intel_bufmgr_fake.c @@ -34,11 +34,17 @@   * the bugs in the old texture manager.   */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +  #include <stdlib.h>  #include <string.h>  #include <assert.h> -#include "dri_bufmgr.h" +#include <errno.h> +#include <xf86drm.h>  #include "intel_bufmgr.h" +#include "intel_bufmgr_priv.h"  #include "drm.h"  #include "i915_drm.h"  #include "mm.h" @@ -105,7 +111,6 @@ struct block {  typedef struct _bufmgr_fake {     dri_bufmgr bufmgr; -   struct intel_bufmgr intel_bufmgr;     unsigned long low_offset;     unsigned long size; @@ -138,14 +143,32 @@ typedef struct _bufmgr_fake {     /**      * Driver callback to emit a fence, returning the cookie.      * +    * This allows the driver to hook in a replacement for the DRM usage in +    * bufmgr_fake. +    *      * Currently, this also requires that a write flush be emitted before      * emitting the fence, but this should change.      */     unsigned int (*fence_emit)(void *private);     /** Driver callback to wait for a fence cookie to have passed. */ -   int (*fence_wait)(void *private, unsigned int fence_cookie); +   void (*fence_wait)(unsigned int fence, void *private); +   void *fence_priv; + +   /** +    * Driver callback to execute a buffer. +    * +    * This allows the driver to hook in a replacement for the DRM usage in +    * bufmgr_fake. +    */ +   int (*exec)(dri_bo *bo, unsigned int used, void *priv); +   void *exec_priv; +     /** Driver-supplied argument to driver callbacks */     void *driver_priv; +   /* Pointer to kernel-updated sarea data for the last completed user irq */ +   volatile int *last_dispatch; + +   int fd;     int debug; @@ -211,24 +234,161 @@ static int FENCE_LTE( unsigned a, unsigned b )     return 0;  } +void intel_bufmgr_fake_set_fence_callback(dri_bufmgr *bufmgr, +					  unsigned int (*emit)(void *priv), +					  void (*wait)(unsigned int fence, +						       void *priv), +					  void *priv) +{ +   dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + +   bufmgr_fake->fence_emit = emit; +   bufmgr_fake->fence_wait = wait; +   bufmgr_fake->fence_priv = priv; +} +  static unsigned int  _fence_emit_internal(dri_bufmgr_fake *bufmgr_fake)  { -   bufmgr_fake->last_fence = bufmgr_fake->fence_emit(bufmgr_fake->driver_priv); +   struct drm_i915_irq_emit ie; +   int ret, seq = 1; + +   if (bufmgr_fake->fence_emit != NULL) +      return bufmgr_fake->fence_emit(bufmgr_fake->fence_priv); + +   ie.irq_seq = &seq; +   ret = drmCommandWriteRead(bufmgr_fake->fd, DRM_I915_IRQ_EMIT, +			     &ie, sizeof(ie)); +   if (ret) { +      drmMsg("%s: drm_i915_irq_emit: %d\n", __FUNCTION__, ret); +      abort(); +   } + +   DBG("emit 0x%08x\n", seq); +   bufmgr_fake->last_fence = seq;     return bufmgr_fake->last_fence;  }  static void -_fence_wait_internal(dri_bufmgr_fake *bufmgr_fake, unsigned int cookie) +_fence_wait_internal(dri_bufmgr_fake *bufmgr_fake, int seq)  { +   struct drm_i915_irq_wait iw; +   int hw_seq, busy_count = 0;     int ret; +   int kernel_lied; + +   if (bufmgr_fake->fence_wait != NULL) { +      bufmgr_fake->fence_wait(seq, bufmgr_fake->fence_priv); +      return; +   } + +   DBG("wait 0x%08x\n", iw.irq_seq); + +   iw.irq_seq = seq; + +   /* The kernel IRQ_WAIT implementation is all sorts of broken. +    * 1) It returns 1 to 0x7fffffff instead of using the full 32-bit unsigned +    *    range. +    * 2) It returns 0 if hw_seq >= seq, not seq - hw_seq < 0 on the 32-bit +    *    signed range. +    * 3) It waits if seq < hw_seq, not seq - hw_seq > 0 on the 32-bit +    *    signed range. +    * 4) It returns -EBUSY in 3 seconds even if the hardware is still +    *    successfully chewing through buffers. +    * +    * Assume that in userland we treat sequence numbers as ints, which makes +    * some of the comparisons convenient, since the sequence numbers are +    * all postive signed integers. +    * +    * From this we get several cases we need to handle.  Here's a timeline. +    * 0x2   0x7                                         0x7ffffff8   0x7ffffffd +    *   |    |                                                   |    | +    * ------------------------------------------------------------------- +    * +    * A) Normal wait for hw to catch up +    * hw_seq seq +    *   |    | +    * ------------------------------------------------------------------- +    * seq - hw_seq = 5.  If we call IRQ_WAIT, it will wait for hw to catch up. +    * +    * B) Normal wait for a sequence number that's already passed. +    * seq    hw_seq +    *   |    | +    * ------------------------------------------------------------------- +    * seq - hw_seq = -5.  If we call IRQ_WAIT, it returns 0 quickly. +    * +    * C) Hardware has already wrapped around ahead of us +    * hw_seq                                                         seq +    *   |                                                             | +    * ------------------------------------------------------------------- +    * seq - hw_seq = 0x80000000 - 5.  If we called IRQ_WAIT, it would wait +    * for hw_seq >= seq, which may never occur.  Thus, we want to catch this +    * in userland and return 0. +    * +    * D) We've wrapped around ahead of the hardware. +    * seq                                                           hw_seq +    *   |                                                             | +    * ------------------------------------------------------------------- +    * seq - hw_seq = -(0x80000000 - 5).  If we called IRQ_WAIT, it would return +    * 0 quickly because hw_seq >= seq, even though the hardware isn't caught up. +    * Thus, we need to catch this early return in userland and bother the +    * kernel until the hardware really does catch up. +    * +    * E) Hardware might wrap after we test in userland. +    *                                                         hw_seq  seq +    *                                                            |    | +    * ------------------------------------------------------------------- +    * seq - hw_seq = 5.  If we call IRQ_WAIT, it will likely see seq >= hw_seq +    * and wait.  However, suppose hw_seq wraps before we make it into the +    * kernel.  The kernel sees hw_seq >= seq and waits for 3 seconds then +    * returns -EBUSY.  This is case C).  We should catch this and then return +    * successfully. +    * +    * F) Hardware might take a long time on a buffer. +    * hw_seq seq +    *   |    | +    * ------------------------------------------------------------------- +    * seq - hw_seq = 5.  If we call IRQ_WAIT, if sequence 2 through 5 take too +    * long, it will return -EBUSY.  Batchbuffers in the gltestperf demo were +    * seen to take up to 7 seconds.  We should catch early -EBUSY return +    * and keep trying. +    */ + +   do { +      /* Keep a copy of last_dispatch so that if the wait -EBUSYs because the +       * hardware didn't catch up in 3 seconds, we can see if it at least made +       * progress and retry. +       */ +      hw_seq = *bufmgr_fake->last_dispatch; + +      /* Catch case C */ +      if (seq - hw_seq > 0x40000000) +	 return; + +      ret = drmCommandWrite(bufmgr_fake->fd, DRM_I915_IRQ_WAIT, +			    &iw, sizeof(iw)); +      /* Catch case D */ +      kernel_lied = (ret == 0) && (seq - *bufmgr_fake->last_dispatch < +				   -0x40000000); + +      /* Catch case E */ +      if (ret == -EBUSY && (seq - *bufmgr_fake->last_dispatch > 0x40000000)) +	 ret = 0; + +      /* Catch case F: Allow up to 15 seconds chewing on one buffer. */ +      if ((ret == -EBUSY) && (hw_seq != *bufmgr_fake->last_dispatch)) +	 busy_count = 0; +      else +	 busy_count++; +   } while (kernel_lied || ret == -EAGAIN || ret == -EINTR || +	    (ret == -EBUSY && busy_count < 5)); -   ret = bufmgr_fake->fence_wait(bufmgr_fake->driver_priv, cookie);     if (ret != 0) { -      drmMsg("%s:%d: Error %d waiting for fence.\n", __FILE__, __LINE__); +      drmMsg("%s:%d: Error waiting for fence: %s.\n", __FILE__, __LINE__, +	     strerror(-ret));        abort();     } -   clear_fenced(bufmgr_fake, cookie); +   clear_fenced(bufmgr_fake, seq);  }  static int @@ -540,7 +700,7 @@ dri_bufmgr_fake_wait_idle(dri_bufmgr_fake *bufmgr_fake)  {     unsigned int cookie; -   cookie = bufmgr_fake->fence_emit(bufmgr_fake->driver_priv); +   cookie = _fence_emit_internal(bufmgr_fake);     _fence_wait_internal(bufmgr_fake, cookie);  } @@ -1052,38 +1212,6 @@ dri_fake_reloc_and_validate_buffer(dri_bo *bo)     return dri_fake_bo_validate(bo);  } -static void * -dri_fake_process_relocs(dri_bo *batch_buf) -{ -   dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)batch_buf->bufmgr; -   dri_bo_fake *batch_fake = (dri_bo_fake *)batch_buf; -   int ret; -   int retry_count = 0; - -   bufmgr_fake->performed_rendering = 0; - -   dri_fake_calculate_domains(batch_buf); - -   batch_fake->read_domains = I915_GEM_DOMAIN_COMMAND; - -   /* we've ran out of RAM so blow the whole lot away and retry */ - restart: -   ret = dri_fake_reloc_and_validate_buffer(batch_buf); -   if (bufmgr_fake->fail == 1) { -      if (retry_count == 0) { -         retry_count++; -         dri_fake_kick_all(bufmgr_fake); -         bufmgr_fake->fail = 0; -         goto restart; -      } else /* dump out the memory here */ -         mmDumpMemInfo(bufmgr_fake->heap); -   } - -   assert(ret == 0); - -   return NULL; -} -  static void  dri_bo_fake_post_submit(dri_bo *bo)  { @@ -1110,12 +1238,74 @@ dri_bo_fake_post_submit(dri_bo *bo)  } -static void -dri_fake_post_submit(dri_bo *batch_buf) +void intel_bufmgr_fake_set_exec_callback(dri_bufmgr *bufmgr, +					 int (*exec)(dri_bo *bo, +						     unsigned int used, +						     void *priv), +					 void *priv) +{ +   dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + +   bufmgr_fake->exec = exec; +   bufmgr_fake->exec_priv = priv; +} + +static int +dri_fake_bo_exec(dri_bo *bo, int used, +		 drm_clip_rect_t *cliprects, int num_cliprects, +		 int DR4)  { -   dri_fake_fence_validated(batch_buf->bufmgr); +   dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bo->bufmgr; +   dri_bo_fake *batch_fake = (dri_bo_fake *)bo; +   struct drm_i915_batchbuffer batch; +   int ret; +   int retry_count = 0; + +   bufmgr_fake->performed_rendering = 0; + +   dri_fake_calculate_domains(bo); -   dri_bo_fake_post_submit(batch_buf); +   batch_fake->read_domains = I915_GEM_DOMAIN_COMMAND; + +   /* we've ran out of RAM so blow the whole lot away and retry */ + restart: +   ret = dri_fake_reloc_and_validate_buffer(bo); +   if (bufmgr_fake->fail == 1) { +      if (retry_count == 0) { +         retry_count++; +         dri_fake_kick_all(bufmgr_fake); +         bufmgr_fake->fail = 0; +         goto restart; +      } else /* dump out the memory here */ +         mmDumpMemInfo(bufmgr_fake->heap); +   } + +   assert(ret == 0); + +   if (bufmgr_fake->exec != NULL) { +      int ret = bufmgr_fake->exec(bo, used, bufmgr_fake->exec_priv); +      if (ret != 0) +	 return ret; +   } else { +      batch.start = bo->offset; +      batch.used = used; +      batch.cliprects = cliprects; +      batch.num_cliprects = num_cliprects; +      batch.DR1 = 0; +      batch.DR4 = DR4; + +      if (drmCommandWrite(bufmgr_fake->fd, DRM_I915_BATCHBUFFER, &batch, +			  sizeof(batch))) { +	 drmMsg("DRM_I915_BATCHBUFFER: %d\n", -errno); +	 return -errno; +      } +   } + +   dri_fake_fence_validated(bo->bufmgr); + +   dri_bo_fake_post_submit(bo); + +   return 0;  }  /** @@ -1187,13 +1377,19 @@ intel_bufmgr_fake_evict_all(dri_bufmgr *bufmgr)        free_block(bufmgr_fake, block);     }  } +void intel_bufmgr_fake_set_last_dispatch(dri_bufmgr *bufmgr, +					 volatile unsigned int *last_dispatch) +{ +   dri_bufmgr_fake *bufmgr_fake = (dri_bufmgr_fake *)bufmgr; + +   bufmgr_fake->last_dispatch = (volatile int *)last_dispatch; +}  dri_bufmgr * -intel_bufmgr_fake_init(unsigned long low_offset, void *low_virtual, +intel_bufmgr_fake_init(int fd, +		       unsigned long low_offset, void *low_virtual,  		       unsigned long size, -		       unsigned int (*fence_emit)(void *private), -		       int (*fence_wait)(void *private, unsigned int cookie), -		       void *driver_priv) +		       volatile unsigned int *last_dispatch)  {     dri_bufmgr_fake *bufmgr_fake; @@ -1216,16 +1412,14 @@ intel_bufmgr_fake_init(unsigned long low_offset, void *low_virtual,     bufmgr_fake->bufmgr.bo_map = dri_fake_bo_map;     bufmgr_fake->bufmgr.bo_unmap = dri_fake_bo_unmap;     bufmgr_fake->bufmgr.bo_wait_rendering = dri_fake_bo_wait_rendering; +   bufmgr_fake->bufmgr.bo_emit_reloc = dri_fake_emit_reloc;     bufmgr_fake->bufmgr.destroy = dri_fake_destroy; -   bufmgr_fake->bufmgr.process_relocs = dri_fake_process_relocs; -   bufmgr_fake->bufmgr.post_submit = dri_fake_post_submit; +   bufmgr_fake->bufmgr.bo_exec = dri_fake_bo_exec;     bufmgr_fake->bufmgr.check_aperture_space = dri_fake_check_aperture_space;     bufmgr_fake->bufmgr.debug = 0; -   bufmgr_fake->intel_bufmgr.emit_reloc = dri_fake_emit_reloc; -   bufmgr_fake->fence_emit = fence_emit; -   bufmgr_fake->fence_wait = fence_wait; -   bufmgr_fake->driver_priv = driver_priv; +   bufmgr_fake->fd = fd; +   bufmgr_fake->last_dispatch = (volatile int *)last_dispatch;     return &bufmgr_fake->bufmgr;  } diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c index af20efb2..4ca49d0a 100644 --- a/libdrm/intel/intel_bufmgr_gem.c +++ b/libdrm/intel/intel_bufmgr_gem.c @@ -34,6 +34,10 @@   *	    Dave Airlie <airlied@linux.ie>   */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +  #include <xf86drm.h>  #include <stdio.h>  #include <stdlib.h> @@ -44,8 +48,8 @@  #include <sys/mman.h>  #include "errno.h" -#include "dri_bufmgr.h"  #include "intel_bufmgr.h" +#include "intel_bufmgr_priv.h"  #include "string.h"  #include "i915_drm.h" @@ -76,8 +80,6 @@ struct dri_gem_bo_bucket {  typedef struct _dri_bufmgr_gem {      dri_bufmgr bufmgr; -    struct intel_bufmgr intel_bufmgr; -      int fd;      int max_relocs; @@ -89,8 +91,6 @@ typedef struct _dri_bufmgr_gem {      /** Array of lists of cached gem objects of power-of-two sizes */      struct dri_gem_bo_bucket cache_bucket[INTEL_GEM_BO_BUCKETS]; - -    struct drm_i915_gem_execbuffer exec_arg;  } dri_bufmgr_gem;  struct _dri_bo_gem { @@ -316,7 +316,7 @@ dri_gem_bo_alloc(dri_bufmgr *bufmgr, const char *name,  	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CREATE, &create);  	bo_gem->gem_handle = create.handle; -	bo_gem->bo.handle = bo_gem->gem_handle; +	//bo_gem->bo.handle = bo_gem->gem_handle;  	if (ret != 0) {  	    free(bo_gem);  	    return NULL; @@ -358,7 +358,7 @@ intel_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,      ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_GEM_OPEN, &open_arg);      if (ret != 0) {  	fprintf(stderr, "Couldn't reference %s handle 0x%08x: %s\n", -	       name, handle, strerror(-ret)); +	       name, handle, strerror(errno));  	free(bo_gem);  	return NULL;      } @@ -370,6 +370,7 @@ intel_bo_gem_create_from_name(dri_bufmgr *bufmgr, const char *name,      bo_gem->refcount = 1;      bo_gem->validate_index = -1;      bo_gem->gem_handle = open_arg.handle; +    bo_gem->global_name = handle;      DBG("bo_create_from_handle: %d (%s)\n", handle, bo_gem->name); @@ -401,7 +402,7 @@ dri_gem_bo_free(dri_bo *bo)      if (ret != 0) {  	fprintf(stderr,  		"DRM_IOCTL_GEM_CLOSE %d failed (%s): %s\n", -		bo_gem->gem_handle, bo_gem->name, strerror(-ret)); +		bo_gem->gem_handle, bo_gem->name, strerror(errno));      }      free(bo);  } @@ -650,8 +651,8 @@ dri_bufmgr_gem_destroy(dri_bufmgr *bufmgr)   * last known offset in target_bo.   */  static int -dri_gem_emit_reloc(dri_bo *bo, uint32_t read_domains, uint32_t write_domain, -		   uint32_t delta, uint32_t offset, dri_bo *target_bo) +dri_gem_bo_emit_reloc(dri_bo *bo, uint32_t read_domains, uint32_t write_domain, +		      uint32_t delta, uint32_t offset, dri_bo *target_bo)  {      dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;      dri_bo_gem *bo_gem = (dri_bo_gem *)bo; @@ -708,27 +709,6 @@ dri_gem_bo_process_reloc(dri_bo *bo)      }  } -static void * -dri_gem_process_reloc(dri_bo *batch_buf) -{ -    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *) batch_buf->bufmgr; - -    /* Update indices and set up the validate list. */ -    dri_gem_bo_process_reloc(batch_buf); - -    /* Add the batch buffer to the validation list.  There are no relocations -     * pointing to it. -     */ -    intel_add_validate_buffer(batch_buf); - -    bufmgr_gem->exec_arg.buffers_ptr = (uintptr_t)bufmgr_gem->exec_objects; -    bufmgr_gem->exec_arg.buffer_count = bufmgr_gem->exec_count; -    bufmgr_gem->exec_arg.batch_start_offset = 0; -    bufmgr_gem->exec_arg.batch_len = 0;	/* written in intel_exec_ioctl */ - -    return &bufmgr_gem->exec_arg; -} -  static void  intel_update_buffer_offsets (dri_bufmgr_gem *bufmgr_gem)  { @@ -748,11 +728,35 @@ intel_update_buffer_offsets (dri_bufmgr_gem *bufmgr_gem)      }  } -static void -dri_gem_post_submit(dri_bo *batch_buf) +static int +dri_gem_bo_exec(dri_bo *bo, int used, +		drm_clip_rect_t *cliprects, int num_cliprects, +		int DR4)  { -    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)batch_buf->bufmgr; -    int i; +    dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr; +    struct drm_i915_gem_execbuffer execbuf; +    int ret, i; + +    /* Update indices and set up the validate list. */ +    dri_gem_bo_process_reloc(bo); + +    /* Add the batch buffer to the validation list.  There are no relocations +     * pointing to it. +     */ +    intel_add_validate_buffer(bo); + +    execbuf.buffers_ptr = (uintptr_t)bufmgr_gem->exec_objects; +    execbuf.buffer_count = bufmgr_gem->exec_count; +    execbuf.batch_start_offset = 0; +    execbuf.batch_len = used; +    execbuf.cliprects_ptr = (uintptr_t)cliprects; +    execbuf.num_cliprects = num_cliprects; +    execbuf.DR1 = 0; +    execbuf.DR4 = DR4; + +    do { +	ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_EXECBUFFER, &execbuf); +    } while (ret == -EAGAIN);      intel_update_buffer_offsets (bufmgr_gem); @@ -772,10 +776,12 @@ dri_gem_post_submit(dri_bo *batch_buf)  	bufmgr_gem->exec_bos[i] = NULL;      }      bufmgr_gem->exec_count = 0; + +    return 0;  }  static int -dri_gem_pin(dri_bo *bo, uint32_t alignment) +dri_gem_bo_pin(dri_bo *bo, uint32_t alignment)  {      dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;      dri_bo_gem *bo_gem = (dri_bo_gem *)bo; @@ -794,7 +800,7 @@ dri_gem_pin(dri_bo *bo, uint32_t alignment)  }  static int -dri_gem_unpin(dri_bo *bo) +dri_gem_bo_unpin(dri_bo *bo)  {      dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;      dri_bo_gem *bo_gem = (dri_bo_gem *)bo; @@ -811,7 +817,7 @@ dri_gem_unpin(dri_bo *bo)  }  static int -dri_gem_set_tiling(dri_bo *bo, uint32_t *tiling_mode) +dri_gem_bo_set_tiling(dri_bo *bo, uint32_t *tiling_mode)  {      dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;      dri_bo_gem *bo_gem = (dri_bo_gem *)bo; @@ -832,7 +838,7 @@ dri_gem_set_tiling(dri_bo *bo, uint32_t *tiling_mode)  }  static int -dri_gem_flink(dri_bo *bo, uint32_t *name) +dri_gem_bo_flink(dri_bo *bo, uint32_t *name)  {      dri_bufmgr_gem *bufmgr_gem = (dri_bufmgr_gem *)bo->bufmgr;      dri_bo_gem *bo_gem = (dri_bo_gem *)bo; @@ -910,16 +916,15 @@ intel_bufmgr_gem_init(int fd, int batch_size)      bufmgr_gem->bufmgr.bo_subdata = dri_gem_bo_subdata;      bufmgr_gem->bufmgr.bo_get_subdata = dri_gem_bo_get_subdata;      bufmgr_gem->bufmgr.bo_wait_rendering = dri_gem_bo_wait_rendering; +    bufmgr_gem->bufmgr.bo_emit_reloc = dri_gem_bo_emit_reloc; +    bufmgr_gem->bufmgr.bo_pin = dri_gem_bo_pin; +    bufmgr_gem->bufmgr.bo_unpin = dri_gem_bo_unpin; +    bufmgr_gem->bufmgr.bo_set_tiling = dri_gem_bo_set_tiling; +    bufmgr_gem->bufmgr.bo_flink = dri_gem_bo_flink; +    bufmgr_gem->bufmgr.bo_exec = dri_gem_bo_exec;      bufmgr_gem->bufmgr.destroy = dri_bufmgr_gem_destroy; -    bufmgr_gem->bufmgr.process_relocs = dri_gem_process_reloc; -    bufmgr_gem->bufmgr.post_submit = dri_gem_post_submit;      bufmgr_gem->bufmgr.debug = 0;      bufmgr_gem->bufmgr.check_aperture_space = dri_gem_check_aperture_space; -    bufmgr_gem->intel_bufmgr.emit_reloc = dri_gem_emit_reloc; -    bufmgr_gem->intel_bufmgr.pin = dri_gem_pin; -    bufmgr_gem->intel_bufmgr.unpin = dri_gem_unpin; -    bufmgr_gem->intel_bufmgr.set_tiling = dri_gem_set_tiling; -    bufmgr_gem->intel_bufmgr.flink = dri_gem_flink;      /* Initialize the linked lists for BO reuse cache. */      for (i = 0; i < INTEL_GEM_BO_BUCKETS; i++)  	bufmgr_gem->cache_bucket[i].tail = &bufmgr_gem->cache_bucket[i].head; @@ -927,67 +932,3 @@ intel_bufmgr_gem_init(int fd, int batch_size)      return &bufmgr_gem->bufmgr;  } -int -intel_bo_emit_reloc(dri_bo *reloc_buf, -		    uint32_t read_domains, uint32_t write_domain, -		    uint32_t delta, uint32_t offset, dri_bo *target_buf) -{ -    struct intel_bufmgr *intel_bufmgr; - -    intel_bufmgr = (struct intel_bufmgr *)(reloc_buf->bufmgr + 1); - -    return intel_bufmgr->emit_reloc(reloc_buf, read_domains, write_domain, -				    delta, offset, target_buf); -} - -int -intel_bo_pin(dri_bo *bo, uint32_t alignment) -{ -    struct intel_bufmgr *intel_bufmgr; - -    intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1); - -    if (intel_bufmgr->pin) -	return intel_bufmgr->pin(bo, alignment); - -    return 0; -} - -int -intel_bo_unpin(dri_bo *bo) -{ -    struct intel_bufmgr *intel_bufmgr; - -    intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1); - -    if (intel_bufmgr->unpin) -	return intel_bufmgr->unpin(bo); - -    return 0; -} - -int intel_bo_set_tiling(dri_bo *bo, uint32_t *tiling_mode) -{ -    struct intel_bufmgr *intel_bufmgr; - -    intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1); - -    if (intel_bufmgr->set_tiling) -	return intel_bufmgr->set_tiling (bo, tiling_mode); - -    *tiling_mode = I915_TILING_NONE; -    return 0; -} - -int intel_bo_flink(dri_bo *bo, uint32_t *name) -{ -    struct intel_bufmgr *intel_bufmgr; - -    intel_bufmgr = (struct intel_bufmgr *)(bo->bufmgr + 1); - -    if (intel_bufmgr->flink) -	return intel_bufmgr->flink (bo, name); - -    return -ENODEV; -} - diff --git a/libdrm/intel/intel_bufmgr_priv.h b/libdrm/intel/intel_bufmgr_priv.h new file mode 100644 index 00000000..7f39bfc2 --- /dev/null +++ b/libdrm/intel/intel_bufmgr_priv.h @@ -0,0 +1,165 @@ +/* + * Copyright © 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + *    Eric Anholt <eric@anholt.net> + * + */ + +/** + * @file intel_bufmgr_priv.h + * + * Private definitions of Intel-specific bufmgr functions and structures. + */ + +#ifndef INTEL_BUFMGR_PRIV_H +#define INTEL_BUFMGR_PRIV_H + +/** + * Context for a buffer manager instance. + * + * Contains public methods followed by private storage for the buffer manager. + */ +struct _dri_bufmgr { +   /** +    * Allocate a buffer object. +    * +    * Buffer objects are not necessarily initially mapped into CPU virtual +    * address space or graphics device aperture.  They must be mapped using +    * bo_map() to be used by the CPU, and validated for use using bo_validate() +    * to be used from the graphics device. +    */ +   dri_bo *(*bo_alloc)(dri_bufmgr *bufmgr_ctx, const char *name, +		       unsigned long size, unsigned int alignment); + +   /** Takes a reference on a buffer object */ +   void (*bo_reference)(dri_bo *bo); + +   /** +    * Releases a reference on a buffer object, freeing the data if +    * rerefences remain. +    */ +   void (*bo_unreference)(dri_bo *bo); + +   /** +    * Maps the buffer into userspace. +    * +    * This function will block waiting for any existing execution on the +    * buffer to complete, first.  The resulting mapping is available at +    * buf->virtual. +    */ +   int (*bo_map)(dri_bo *buf, int write_enable); + +   /** Reduces the refcount on the userspace mapping of the buffer object. */ +   int (*bo_unmap)(dri_bo *buf); + +   /** +    * Write data into an object. +    * +    * This is an optional function, if missing, +    * dri_bo will map/memcpy/unmap. +    */ +   int (*bo_subdata) (dri_bo *buf, unsigned long offset, +		      unsigned long size, const void *data); + +   /** +    * Read data from an object +    * +    * This is an optional function, if missing, +    * dri_bo will map/memcpy/unmap. +    */ +   int (*bo_get_subdata) (dri_bo *bo, unsigned long offset, +			  unsigned long size, void *data); + +   /** +    * Waits for rendering to an object by the GPU to have completed. +    * +    * This is not required for any access to the BO by bo_map, bo_subdata, etc. +    * It is merely a way for the driver to implement glFinish. +    */ +   void (*bo_wait_rendering) (dri_bo *bo); + +   /** +    * Tears down the buffer manager instance. +    */ +   void (*destroy)(dri_bufmgr *bufmgr); + +    /** +     * Add relocation entry in reloc_buf, which will be updated with the +     * target buffer's real offset on on command submission. +     * +     * Relocations remain in place for the lifetime of the buffer object. +     * +     * \param reloc_buf Buffer to write the relocation into. +     * \param read_domains GEM read domains which the buffer will be read into +     *	      by the command that this relocation is part of. +     * \param write_domains GEM read domains which the buffer will be dirtied +     *	      in by the command that this relocation is part of. +     * \param delta Constant value to be added to the relocation target's +     *	       offset. +     * \param offset Byte offset within batch_buf of the relocated pointer. +     * \param target Buffer whose offset should be written into the relocation +     *	     entry. +     */ +    int (*bo_emit_reloc)(dri_bo *reloc_buf, +			 uint32_t read_domains, uint32_t write_domain, +			 uint32_t delta, uint32_t offset, dri_bo *target); + +    /** Executes the command buffer pointed to by bo. */ +    int (*bo_exec)(dri_bo *bo, int used, +		   drm_clip_rect_t *cliprects, int num_cliprects, +		   int DR4); + +    /** +     * Pin a buffer to the aperture and fix the offset until unpinned +     * +     * \param buf Buffer to pin +     * \param alignment Required alignment for aperture, in bytes +     */ +    int (*bo_pin) (dri_bo *buf, uint32_t alignment); +    /** +     * Unpin a buffer from the aperture, allowing it to be removed +     * +     * \param buf Buffer to unpin +     */ +    int (*bo_unpin) (dri_bo *buf); +    /** +     * Ask that the buffer be placed in tiling mode +     * +     * \param buf Buffer to set tiling mode for +     * \param tiling_mode desired, and returned tiling mode +     */ +    int (*bo_set_tiling) (dri_bo *bo, uint32_t *tiling_mode); +    /** +     * Create a visible name for a buffer which can be used by other apps +     * +     * \param buf Buffer to create a name for +     * \param name Returned name +     */ +    int (*bo_flink) (dri_bo *buf, uint32_t *name); + +    int (*check_aperture_space)(dri_bo **bo_array, int count); +    int debug; /**< Enables verbose debugging printouts */ +}; + +#endif /* INTEL_BUFMGR_PRIV_H */ + diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c index 64765339..94f5dfad 100644 --- a/libdrm/xf86drm.c +++ b/libdrm/xf86drm.c @@ -178,7 +178,7 @@ static char *drmStrdup(const char *s)   * Call ioctl, restarting if it is interupted   */  static int -drmIoctl(int fd, int request, void *arg) +drmIoctl(int fd, unsigned long request, void *arg)  {      int	ret; @@ -300,6 +300,7 @@ static int drmOpenDevice(long dev, int minor, int type)  	group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;      } +#if !defined(UDEV)      if (stat(DRM_DIR_NAME, &st)) {  	if (!isroot)  	    return DRM_ERR_NOT_ROOT; @@ -320,6 +321,30 @@ static int drmOpenDevice(long dev, int minor, int type)  	chown(buf, user, group);  	chmod(buf, devmode);      } +#else +    /* if we modprobed then wait for udev */ +    { +	int udev_count = 0; +wait_for_udev: +        if (stat(DRM_DIR_NAME, &st)) { +		usleep(20); +		udev_count++; + +		if (udev_count == 50) +			return -1; +		goto wait_for_udev; +	} + +    	if (stat(buf, &st)) { +		usleep(20); +		udev_count++; + +		if (udev_count == 50) +			return -1; +		goto wait_for_udev; +    	} +    } +#endif      fd = open(buf, O_RDWR, 0);      drmMsg("drmOpenDevice: open result is %d, (%s)\n", | 
