diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_buffer.h | 36 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c | 150 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h | 21 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c | 20 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr.h | 2 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c | 23 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c | 26 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c | 2 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c | 25 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c | 25 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c | 21 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_validate.c | 84 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_validate.h | 10 | ||||
| -rw-r--r-- | src/gallium/auxiliary/pipebuffer/pb_winsys.c | 22 | 
14 files changed, 359 insertions, 108 deletions
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer.h b/src/gallium/auxiliary/pipebuffer/pb_buffer.h index fb0ba15948..7cba5fa441 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer.h @@ -37,7 +37,7 @@   * There is no obligation of a winsys driver to use this library. And a pipe   * driver should be completly agnostic about it.   *  - * \author Jos� Fonseca <jrfonseca@tungstengraphics.com> + * \author Jose Fonseca <jrfonseca@tungstengraphics.com>   */  #ifndef PB_BUFFER_H_ @@ -46,6 +46,7 @@  #include "pipe/p_compiler.h"  #include "pipe/p_debug.h" +#include "pipe/p_error.h"  #include "pipe/p_state.h"  #include "pipe/p_inlines.h" @@ -56,6 +57,8 @@ extern "C" {  struct pb_vtbl; +struct pb_validate; +  /**   * Buffer description. @@ -104,6 +107,13 @@ struct pb_vtbl     void (*unmap)( struct pb_buffer *buf ); +   enum pipe_error (*validate)( struct pb_buffer *buf,  +                                struct pb_validate *vl, +                                unsigned flags ); + +   void (*fence)( struct pb_buffer *buf,  +                  struct pipe_fence_handle *fence ); +     /**      * Get the base buffer and the offset.      *  @@ -118,6 +128,7 @@ struct pb_vtbl     void (*get_base_buffer)( struct pb_buffer *buf,                              struct pb_buffer **base_buf,                              unsigned *offset ); +     }; @@ -176,12 +187,35 @@ pb_get_base_buffer( struct pb_buffer *buf,        return;     }     assert(buf->base.refcount > 0); +   assert(buf->vtbl->get_base_buffer);     buf->vtbl->get_base_buffer(buf, base_buf, offset);     assert(*base_buf);     assert(*offset < (*base_buf)->base.size);  } +static INLINE enum pipe_error  +pb_validate(struct pb_buffer *buf, struct pb_validate *vl, unsigned flags) +{ +   assert(buf); +   if(!buf) +      return PIPE_ERROR; +   assert(buf->vtbl->validate); +   return buf->vtbl->validate(buf, vl, flags); +} + + +static INLINE void  +pb_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence) +{ +   assert(buf); +   if(!buf) +      return; +   assert(buf->vtbl->fence); +   buf->vtbl->fence(buf, fence); +} + +  static INLINE void   pb_destroy(struct pb_buffer *buf)  { diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 17b2781052..aa4b096274 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -29,7 +29,7 @@   * \file   * Implementation of fenced buffers.   *  - * \author José Fonseca <jrfonseca-at-tungstengraphics-dot-com> + * \author Jose Fonseca <jrfonseca-at-tungstengraphics-dot-com>   * \author Thomas Hellström <thomas-at-tungstengraphics-dot-com>   */ @@ -59,13 +59,6 @@   */  #define SUPER(__derived) (&(__derived)->base) -#define PIPE_BUFFER_USAGE_CPU_READ_WRITE \ -   ( PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE ) -#define PIPE_BUFFER_USAGE_GPU_READ_WRITE \ -   ( PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE ) -#define PIPE_BUFFER_USAGE_WRITE \ -   ( PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_GPU_WRITE ) -  struct fenced_buffer_list  { @@ -97,6 +90,8 @@ struct fenced_buffer     unsigned flags;     unsigned mapcount; +   struct pb_validate *vl; +   unsigned validation_flags;     struct pipe_fence_handle *fence;     struct list_head head; @@ -108,7 +103,6 @@ static INLINE struct fenced_buffer *  fenced_buffer(struct pb_buffer *buf)  {     assert(buf); -   assert(buf->vtbl == &fenced_buffer_vtbl);     return (struct fenced_buffer *)buf;  } @@ -274,6 +268,7 @@ fenced_buffer_map(struct pb_buffer *buf,     struct fenced_buffer *fenced_buf = fenced_buffer(buf);     void *map; +   assert(flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE);     assert(!(flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE));     flags &= PIPE_BUFFER_USAGE_CPU_READ_WRITE; @@ -315,6 +310,93 @@ fenced_buffer_unmap(struct pb_buffer *buf)  } +static enum pipe_error +fenced_buffer_validate(struct pb_buffer *buf, +                       struct pb_validate *vl, +                       unsigned flags) +{ +   struct fenced_buffer *fenced_buf = fenced_buffer(buf); +   enum pipe_error ret; +    +   if(!vl) { +      /* invalidate */ +      fenced_buf->vl = NULL; +      fenced_buf->validation_flags = 0; +      return PIPE_OK; +   } +    +   assert(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE); +   assert(!(flags & ~PIPE_BUFFER_USAGE_GPU_READ_WRITE)); +   flags &= PIPE_BUFFER_USAGE_GPU_READ_WRITE; + +   /* Buffer cannot be validated in two different lists */  +   if(fenced_buf->vl && fenced_buf->vl != vl) +      return PIPE_ERROR_RETRY; +    +   /* Do not validate if buffer is still mapped */ +   if(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) { +      /* TODO: wait for the thread that mapped the buffer to unmap it */ +      return PIPE_ERROR_RETRY; +   } + +   if(fenced_buf->vl == vl && +      (fenced_buf->validation_flags & flags) == flags) { +      /* Nothing to do -- buffer already validated */ +      return PIPE_OK; +   } + +   /* Final sanity checking */ +   assert(!(fenced_buf->flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE)); +   assert(!fenced_buf->mapcount); +    +   ret = pb_validate(fenced_buf->buffer, vl, flags); +   if (ret != PIPE_OK) +      return ret; +    +   fenced_buf->vl = vl; +   fenced_buf->validation_flags |= flags; +    +   return PIPE_OK; +} + + +static void +fenced_buffer_fence(struct pb_buffer *buf, +                    struct pipe_fence_handle *fence) +{ +   struct fenced_buffer *fenced_buf; +   struct fenced_buffer_list *fenced_list; +   struct pipe_winsys *winsys; + +   fenced_buf = fenced_buffer(buf); +   fenced_list = fenced_buf->list; +   winsys = fenced_list->winsys; +    +   if(fence == fenced_buf->fence) { +      /* Nothing to do */ +      return; +   } + +   assert(fenced_buf->vl); +   assert(fenced_buf->validation_flags); +    +   pipe_mutex_lock(fenced_list->mutex); +   if (fenced_buf->fence) +      _fenced_buffer_remove(fenced_list, fenced_buf); +   if (fence) { +      winsys->fence_reference(winsys, &fenced_buf->fence, fence); +      fenced_buf->flags |= fenced_buf->validation_flags; +      _fenced_buffer_add(fenced_buf); +   } +   pipe_mutex_unlock(fenced_list->mutex); +    +   pb_fence(fenced_buf->buffer, fence); + +   fenced_buf->vl = NULL; +   fenced_buf->validation_flags = 0; +} + +  static void  fenced_buffer_get_base_buffer(struct pb_buffer *buf,                                struct pb_buffer **base_buf, @@ -325,11 +407,13 @@ fenced_buffer_get_base_buffer(struct pb_buffer *buf,  } -const struct pb_vtbl  +static const struct pb_vtbl   fenced_buffer_vtbl = {        fenced_buffer_destroy,        fenced_buffer_map,        fenced_buffer_unmap, +      fenced_buffer_validate, +      fenced_buffer_fence,        fenced_buffer_get_base_buffer  }; @@ -362,52 +446,6 @@ fenced_buffer_create(struct fenced_buffer_list *fenced_list,  } -void -buffer_fence(struct pb_buffer *buf, -             struct pipe_fence_handle *fence) -{ -   struct fenced_buffer *fenced_buf; -   struct fenced_buffer_list *fenced_list; -   struct pipe_winsys *winsys; -   /* FIXME: receive this as a parameter */ -   unsigned flags = fence ? PIPE_BUFFER_USAGE_GPU_READ_WRITE : 0; - -   /* This is a public function, so be extra cautious with the buffer passed,  -    * as happens frequently to receive null buffers, or pointer to buffers  -    * other than fenced buffers. */ -   assert(buf); -   if(!buf) -      return; -   assert(buf->vtbl == &fenced_buffer_vtbl); -   if(buf->vtbl != &fenced_buffer_vtbl) -      return; -    -   fenced_buf = fenced_buffer(buf); -   fenced_list = fenced_buf->list; -   winsys = fenced_list->winsys; -    -   if(!fence || fence == fenced_buf->fence) { -      /* Handle the same fence case specially, not only because it is a fast  -       * path, but mostly to avoid serializing two writes with the same fence,  -       * as that would bring the hardware down to synchronous operation without -       * any benefit. -       */ -      fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; -      return; -   } -    -   pipe_mutex_lock(fenced_list->mutex); -   if (fenced_buf->fence) -      _fenced_buffer_remove(fenced_list, fenced_buf); -   if (fence) { -      winsys->fence_reference(winsys, &fenced_buf->fence, fence); -      fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE; -      _fenced_buffer_add(fenced_buf); -   } -   pipe_mutex_unlock(fenced_list->mutex); -} - -  struct fenced_buffer_list *  fenced_buffer_list_create(struct pipe_winsys *winsys)   { diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h index 50d5891bdb..b15c676194 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.h @@ -44,7 +44,7 @@   * Between the handle's destruction, and the fence signalling, the buffer is    * stored in a fenced buffer list.   *  - * \author José Fonseca <jrfonseca@tungstengraphics.com> + * \author Jose Fonseca <jrfonseca@tungstengraphics.com>   */  #ifndef PB_BUFFER_FENCED_H_ @@ -71,14 +71,6 @@ struct fenced_buffer_list;  /** - * The fenced buffer's virtual function table. - *  - * NOTE: Made public for debugging purposes. - */ -extern const struct pb_vtbl fenced_buffer_vtbl; - - -/**   * Create a fenced buffer list.   *    * See also fenced_bufmgr_create for a more convenient way to use this. @@ -108,17 +100,6 @@ fenced_buffer_create(struct fenced_buffer_list *fenced,                       struct pb_buffer *buffer); -/** - * Set a buffer's fence. - *  - * NOTE: Although it takes a generic pb_buffer argument, it will fail - * on everything but buffers returned by fenced_buffer_create. - */ -void -buffer_fence(struct pb_buffer *buf, -             struct pipe_fence_handle *fence); - -  #ifdef __cplusplus  }  #endif diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c index 1bf22a2ec0..53f497cfb0 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_malloc.c @@ -81,6 +81,24 @@ malloc_buffer_unmap(struct pb_buffer *buf)  } +static enum pipe_error  +malloc_buffer_validate(struct pb_buffer *buf,  +                       struct pb_validate *vl, +                       unsigned flags) +{ +   assert(0); +   return PIPE_ERROR; +} + + +static void +malloc_buffer_fence(struct pb_buffer *buf,  +                    struct pipe_fence_handle *fence) +{ +   assert(0); +} + +  static void  malloc_buffer_get_base_buffer(struct pb_buffer *buf,                                struct pb_buffer **base_buf, @@ -96,6 +114,8 @@ malloc_buffer_vtbl = {        malloc_buffer_destroy,        malloc_buffer_map,        malloc_buffer_unmap, +      malloc_buffer_validate, +      malloc_buffer_fence,        malloc_buffer_get_base_buffer  }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h index cafbee045a..8fe2704708 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr.h @@ -43,7 +43,7 @@   * - the fenced buffer manager, which will delay buffer destruction until the    * the moment the card finishing processing it.    *  - * \author José Fonseca <jrfonseca@tungstengraphics.com> + * \author Jose Fonseca <jrfonseca@tungstengraphics.com>   */  #ifndef PB_BUFMGR_H_ diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c index 8f118874ec..f57a7bffd7 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_cache.c @@ -29,7 +29,7 @@   * \file   * Buffer cache.   *  - * \author José Fonseca <jrfonseca-at-tungstengraphics-dot-com> + * \author Jose Fonseca <jrfonseca-at-tungstengraphics-dot-com>   * \author Thomas Hellström <thomas-at-tungstengraphics-dot-com>   */ @@ -183,6 +183,25 @@ pb_cache_buffer_unmap(struct pb_buffer *_buf)  } +static enum pipe_error  +pb_cache_buffer_validate(struct pb_buffer *_buf,  +                         struct pb_validate *vl, +                         unsigned flags) +{ +   struct pb_cache_buffer *buf = pb_cache_buffer(_buf); +   return pb_validate(buf->buffer, vl, flags); +} + + +static void +pb_cache_buffer_fence(struct pb_buffer *_buf,  +                      struct pipe_fence_handle *fence) +{ +   struct pb_cache_buffer *buf = pb_cache_buffer(_buf); +   pb_fence(buf->buffer, fence); +} + +  static void  pb_cache_buffer_get_base_buffer(struct pb_buffer *_buf,                                struct pb_buffer **base_buf, @@ -198,6 +217,8 @@ pb_cache_buffer_vtbl = {        pb_cache_buffer_destroy,        pb_cache_buffer_map,        pb_cache_buffer_unmap, +      pb_cache_buffer_validate, +      pb_cache_buffer_fence,        pb_cache_buffer_get_base_buffer  }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c index 1675e6e182..62639fe1c8 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c @@ -29,7 +29,7 @@   * \file   * Debug buffer manager to detect buffer under- and overflows.   *  - * \author José Fonseca <jrfonseca@tungstengraphics.com> + * \author Jose Fonseca <jrfonseca@tungstengraphics.com>   */ @@ -255,11 +255,35 @@ pb_debug_buffer_get_base_buffer(struct pb_buffer *_buf,  } +static enum pipe_error  +pb_debug_buffer_validate(struct pb_buffer *_buf,  +                         struct pb_validate *vl, +                         unsigned flags) +{ +   struct pb_debug_buffer *buf = pb_debug_buffer(_buf); +    +   pb_debug_buffer_check(buf); + +   return pb_validate(buf->buffer, vl, flags); +} + + +static void +pb_debug_buffer_fence(struct pb_buffer *_buf,  +                      struct pipe_fence_handle *fence) +{ +   struct pb_debug_buffer *buf = pb_debug_buffer(_buf); +   pb_fence(buf->buffer, fence); +} + +  const struct pb_vtbl   pb_debug_buffer_vtbl = {        pb_debug_buffer_destroy,        pb_debug_buffer_map,        pb_debug_buffer_unmap, +      pb_debug_buffer_validate, +      pb_debug_buffer_fence,        pb_debug_buffer_get_base_buffer  }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c index e2594ea236..513ed28ca6 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_fenced.c @@ -30,7 +30,7 @@   * \file   * A buffer manager that wraps buffers in fenced buffers.   *  - * \author José Fonseca <jrfonseca@tungstengraphics.dot.com> + * \author Jose Fonseca <jrfonseca@tungstengraphics.dot.com>   */ diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c index d4434c6962..2f5a5d8ea0 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_mm.c @@ -29,7 +29,7 @@   * \file   * Buffer manager using the old texture memory manager.   *  - * \author José Fonseca <jrfonseca@tungstengraphics.com> + * \author Jose Fonseca <jrfonseca@tungstengraphics.com>   */ @@ -124,6 +124,27 @@ mm_buffer_unmap(struct pb_buffer *buf)  } +static enum pipe_error  +mm_buffer_validate(struct pb_buffer *buf,  +                   struct pb_validate *vl, +                   unsigned flags) +{ +   struct mm_buffer *mm_buf = mm_buffer(buf); +   struct mm_pb_manager *mm = mm_buf->mgr; +   return pb_validate(mm->buffer, vl, flags); +} + + +static void +mm_buffer_fence(struct pb_buffer *buf,  +                struct pipe_fence_handle *fence) +{ +   struct mm_buffer *mm_buf = mm_buffer(buf); +   struct mm_pb_manager *mm = mm_buf->mgr; +   pb_fence(mm->buffer, fence); +} + +  static void  mm_buffer_get_base_buffer(struct pb_buffer *buf,                            struct pb_buffer **base_buf, @@ -141,6 +162,8 @@ mm_buffer_vtbl = {        mm_buffer_destroy,        mm_buffer_map,        mm_buffer_unmap, +      mm_buffer_validate, +      mm_buffer_fence,        mm_buffer_get_base_buffer  }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c index 61ac291ed7..a6ff37653e 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_pool.c @@ -30,7 +30,7 @@   * \file   * Batch buffer pool management.   *  - * \author José Fonseca <jrfonseca-at-tungstengraphics-dot-com> + * \author Jose Fonseca <jrfonseca-at-tungstengraphics-dot-com>   * \author Thomas Hellström <thomas-at-tungstengraphics-dot-com>   */ @@ -138,6 +138,27 @@ pool_buffer_unmap(struct pb_buffer *buf)  } +static enum pipe_error  +pool_buffer_validate(struct pb_buffer *buf,  +                     struct pb_validate *vl, +                     unsigned flags) +{ +   struct pool_buffer *pool_buf = pool_buffer(buf); +   struct pool_pb_manager *pool = pool_buf->mgr; +   return pb_validate(pool->buffer, vl, flags); +} + + +static void +pool_buffer_fence(struct pb_buffer *buf,  +                  struct pipe_fence_handle *fence) +{ +   struct pool_buffer *pool_buf = pool_buffer(buf); +   struct pool_pb_manager *pool = pool_buf->mgr; +   pb_fence(pool->buffer, fence); +} + +  static void  pool_buffer_get_base_buffer(struct pb_buffer *buf,                              struct pb_buffer **base_buf, @@ -155,6 +176,8 @@ pool_buffer_vtbl = {        pool_buffer_destroy,        pool_buffer_map,        pool_buffer_unmap, +      pool_buffer_validate, +      pool_buffer_fence,        pool_buffer_get_base_buffer  }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c index 2a80154920..9b9fedccb4 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c +++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_slab.c @@ -248,6 +248,25 @@ pb_slab_buffer_unmap(struct pb_buffer *_buf)  } +static enum pipe_error  +pb_slab_buffer_validate(struct pb_buffer *_buf,  +                         struct pb_validate *vl, +                         unsigned flags) +{ +   struct pb_slab_buffer *buf = pb_slab_buffer(_buf); +   return pb_validate(buf->slab->bo, vl, flags); +} + + +static void +pb_slab_buffer_fence(struct pb_buffer *_buf,  +                      struct pipe_fence_handle *fence) +{ +   struct pb_slab_buffer *buf = pb_slab_buffer(_buf); +   pb_fence(buf->slab->bo, fence); +} + +  static void  pb_slab_buffer_get_base_buffer(struct pb_buffer *_buf,                                 struct pb_buffer **base_buf, @@ -264,6 +283,8 @@ pb_slab_buffer_vtbl = {        pb_slab_buffer_destroy,        pb_slab_buffer_map,        pb_slab_buffer_unmap, +      pb_slab_buffer_validate, +      pb_slab_buffer_fence,        pb_slab_buffer_get_base_buffer  }; diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.c b/src/gallium/auxiliary/pipebuffer/pb_validate.c index 1e54fc39d4..94532bb4ce 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.c +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.c @@ -46,9 +46,16 @@  #define PB_VALIDATE_INITIAL_SIZE 1 /* 512 */  +struct pb_validate_entry +{ +   struct pb_buffer *buf; +   unsigned flags; +}; + +  struct pb_validate  { -   struct pb_buffer **buffers; +   struct pb_validate_entry *entries;     unsigned used;     unsigned size;  }; @@ -56,43 +63,50 @@ struct pb_validate  enum pipe_error  pb_validate_add_buffer(struct pb_validate *vl, -                       struct pb_buffer *buf) +                       struct pb_buffer *buf, +                       unsigned flags)  {     assert(buf);     if(!buf)        return PIPE_ERROR; +   assert(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE); +   assert(!(flags & ~PIPE_BUFFER_USAGE_GPU_READ_WRITE)); +   flags &= PIPE_BUFFER_USAGE_GPU_READ_WRITE; +     /* We only need to store one reference for each buffer, so avoid storing -    * consecutive references for the same buffer. It might not be the more  -    * common pasttern, but it is easy to implement. +    * consecutive references for the same buffer. It might not be the most  +    * common pattern, but it is easy to implement.      */ -   if(vl->used && vl->buffers[vl->used - 1] == buf) { +   if(vl->used && vl->entries[vl->used - 1].buf == buf) { +      vl->entries[vl->used - 1].flags |= flags;        return PIPE_OK;     }     /* Grow the table */     if(vl->used == vl->size) {        unsigned new_size; -      struct pb_buffer **new_buffers; +      struct pb_validate_entry *new_entries;        new_size = vl->size * 2;        if(!new_size)  	 return PIPE_ERROR_OUT_OF_MEMORY; -      new_buffers = (struct pb_buffer **)REALLOC(vl->buffers, -                                                 vl->size*sizeof(struct pb_buffer *), -                                                 new_size*sizeof(struct pb_buffer *)); -      if(!new_buffers) +      new_entries = (struct pb_validate_entry *)REALLOC(vl->entries, +                                                        vl->size*sizeof(struct pb_validate_entry), +                                                        new_size*sizeof(struct pb_validate_entry)); +      if(!new_entries)           return PIPE_ERROR_OUT_OF_MEMORY; -      memset(new_buffers + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_buffer *)); +      memset(new_entries + vl->size, 0, (new_size - vl->size)*sizeof(struct pb_validate_entry));        vl->size = new_size; -      vl->buffers = new_buffers; +      vl->entries = new_entries;     } -   assert(!vl->buffers[vl->used]); -   pb_reference(&vl->buffers[vl->used], buf); +   assert(!vl->entries[vl->used].buf); +   pb_reference(&vl->entries[vl->used].buf, buf); +   vl->entries[vl->used].flags = flags;     ++vl->used;     return PIPE_OK; @@ -100,10 +114,36 @@ pb_validate_add_buffer(struct pb_validate *vl,  enum pipe_error +pb_validate_foreach(struct pb_validate *vl, +                    enum pipe_error (*callback)(struct pb_buffer *buf, void *data), +                    void *data) +{ +   unsigned i; +   for(i = 0; i < vl->used; ++i) { +      enum pipe_error ret; +      ret = callback(vl->entries[i].buf, data); +      if(ret != PIPE_OK) +         return ret; +   } +   return PIPE_OK; +} + + +enum pipe_error  pb_validate_validate(struct pb_validate *vl)   { -   /* FIXME: go through each buffer, ensure its not mapped, its address is  -    * available -- requires a new pb_buffer interface */ +   unsigned i; +    +   for(i = 0; i < vl->used; ++i) { +      enum pipe_error ret; +      ret = pb_validate(vl->entries[i].buf, vl, vl->entries[i].flags); +      if(ret != PIPE_OK) { +         while(i--) +            pb_validate(vl->entries[i].buf, NULL, 0); +         return ret; +      } +   } +     return PIPE_OK;  } @@ -114,8 +154,8 @@ pb_validate_fence(struct pb_validate *vl,  {     unsigned i;     for(i = 0; i < vl->used; ++i) { -      buffer_fence(vl->buffers[i], fence); -      pb_reference(&vl->buffers[i], NULL); +      pb_fence(vl->entries[i].buf, fence); +      pb_reference(&vl->entries[i].buf, NULL);     }     vl->used = 0;  } @@ -126,8 +166,8 @@ pb_validate_destroy(struct pb_validate *vl)  {     unsigned i;     for(i = 0; i < vl->used; ++i) -      pb_reference(&vl->buffers[i], NULL); -   FREE(vl->buffers); +      pb_reference(&vl->entries[i].buf, NULL); +   FREE(vl->entries);     FREE(vl);  } @@ -142,8 +182,8 @@ pb_validate_create()        return NULL;     vl->size = PB_VALIDATE_INITIAL_SIZE; -   vl->buffers = (struct pb_buffer **)CALLOC(vl->size, sizeof(struct pb_buffer *)); -   if(!vl->buffers) { +   vl->entries = (struct pb_validate_entry *)CALLOC(vl->size, sizeof(struct pb_validate_entry)); +   if(!vl->entries) {        FREE(vl);        return NULL;     } diff --git a/src/gallium/auxiliary/pipebuffer/pb_validate.h b/src/gallium/auxiliary/pipebuffer/pb_validate.h index 3db1d5330b..dfb84df1ce 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_validate.h +++ b/src/gallium/auxiliary/pipebuffer/pb_validate.h @@ -58,7 +58,13 @@ struct pb_validate;  enum pipe_error  pb_validate_add_buffer(struct pb_validate *vl, -                       struct pb_buffer *buf); +                       struct pb_buffer *buf, +                       unsigned flags); + +enum pipe_error +pb_validate_foreach(struct pb_validate *vl, +                    enum pipe_error (*callback)(struct pb_buffer *buf, void *data), +                    void *data);  /**   * Validate all buffers for hardware access. @@ -71,7 +77,7 @@ pb_validate_validate(struct pb_validate *vl);  /**   * Fence all buffers and clear the list.   *  - * Should be called right before issuing commands to the hardware. + * Should be called right after issuing commands to the hardware.   */  void  pb_validate_fence(struct pb_validate *vl, diff --git a/src/gallium/auxiliary/pipebuffer/pb_winsys.c b/src/gallium/auxiliary/pipebuffer/pb_winsys.c index e2f1008cc2..452835fdad 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_winsys.c +++ b/src/gallium/auxiliary/pipebuffer/pb_winsys.c @@ -30,7 +30,7 @@   * Implementation of client buffer (also designated as "user buffers"), which   * are just state-tracker owned data masqueraded as buffers.   *  - * \author José Fonseca <jrfonseca@tungstengraphics.com> + * \author Jose Fonseca <jrfonseca@tungstengraphics.com>   */ @@ -92,6 +92,24 @@ pb_user_buffer_unmap(struct pb_buffer *buf)  } +static enum pipe_error  +pb_user_buffer_validate(struct pb_buffer *buf,  +                        struct pb_validate *vl, +                        unsigned flags) +{ +   assert(0); +   return PIPE_ERROR; +} + + +static void +pb_user_buffer_fence(struct pb_buffer *buf,  +                     struct pipe_fence_handle *fence) +{ +   assert(0); +} + +  static void  pb_user_buffer_get_base_buffer(struct pb_buffer *buf,                                 struct pb_buffer **base_buf, @@ -107,6 +125,8 @@ pb_user_buffer_vtbl = {        pb_user_buffer_destroy,        pb_user_buffer_map,        pb_user_buffer_unmap, +      pb_user_buffer_validate, +      pb_user_buffer_fence,        pb_user_buffer_get_base_buffer  };  | 
