Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the
  15.  * next paragraph) shall be included in all copies or substantial portions
  16.  * of the Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  20.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  21.  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
  22.  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  23.  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  24.  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /**
  29.  * \file
  30.  * Generic code for buffers.
  31.  *
  32.  * Behind a pipe buffle handle there can be DMA buffers, client (or user)
  33.  * buffers, regular malloced buffers, etc. This file provides an abstract base
  34.  * buffer handle that allows the driver to cope with all those kinds of buffers
  35.  * in a more flexible way.
  36.  *
  37.  * There is no obligation of a winsys driver to use this library. And a pipe
  38.  * driver should be completly agnostic about it.
  39.  *
  40.  * \author Jose Fonseca <jrfonseca@tungstengraphics.com>
  41.  */
  42.  
  43. #ifndef PB_BUFFER_H_
  44. #define PB_BUFFER_H_
  45.  
  46.  
  47. #include "pipe/p_compiler.h"
  48. #include "util/u_debug.h"
  49. #include "util/u_inlines.h"
  50. #include "pipe/p_defines.h"
  51.  
  52.  
  53. #ifdef __cplusplus
  54. extern "C" {
  55. #endif
  56.  
  57.  
  58. struct pb_vtbl;
  59. struct pb_validate;
  60. struct pipe_fence_handle;
  61.  
  62.  
  63. #define PB_USAGE_CPU_READ  (1 << 0)
  64. #define PB_USAGE_CPU_WRITE (1 << 1)
  65. #define PB_USAGE_GPU_READ  (1 << 2)
  66. #define PB_USAGE_GPU_WRITE (1 << 3)
  67. #define PB_USAGE_UNSYNCHRONIZED (1 << 10)
  68. #define PB_USAGE_DONTBLOCK (1 << 9)
  69.  
  70. #define PB_USAGE_CPU_READ_WRITE \
  71.    ( PB_USAGE_CPU_READ | PB_USAGE_CPU_WRITE )
  72. #define PB_USAGE_GPU_READ_WRITE \
  73.    ( PB_USAGE_GPU_READ | PB_USAGE_GPU_WRITE )
  74. #define PB_USAGE_WRITE \
  75.    ( PB_USAGE_CPU_WRITE | PB_USAGE_GPU_WRITE )
  76.  
  77. /**
  78.  * Buffer description.
  79.  *
  80.  * Used when allocating the buffer.
  81.  */
  82. struct pb_desc
  83. {
  84.    unsigned alignment;
  85.    unsigned usage;
  86. };
  87.  
  88.  
  89. /**
  90.  * Size. Regular (32bit) unsigned for now.
  91.  */
  92. typedef unsigned pb_size;
  93.  
  94.  
  95. /**
  96.  * Base class for all pb_* buffers.
  97.  */
  98. struct pb_buffer
  99. {
  100.    struct pipe_reference  reference;
  101.    unsigned               size;
  102.    unsigned               alignment;
  103.    unsigned               usage;
  104.  
  105.    /**
  106.     * Pointer to the virtual function table.
  107.     *
  108.     * Avoid accessing this table directly. Use the inline functions below
  109.     * instead to avoid mistakes.
  110.     */
  111.    const struct pb_vtbl *vtbl;
  112. };
  113.  
  114.  
  115. /**
  116.  * Virtual function table for the buffer storage operations.
  117.  *
  118.  * Note that creation is not done through this table.
  119.  */
  120. struct pb_vtbl
  121. {
  122.    void (*destroy)( struct pb_buffer *buf );
  123.  
  124.    /**
  125.     * Map the entire data store of a buffer object into the client's address.
  126.     * flags is bitmask of PB_USAGE_CPU_READ/WRITE.
  127.     */
  128.    void *(*map)( struct pb_buffer *buf,
  129.                  unsigned flags, void *flush_ctx );
  130.    
  131.    void (*unmap)( struct pb_buffer *buf );
  132.  
  133.    enum pipe_error (*validate)( struct pb_buffer *buf,
  134.                                 struct pb_validate *vl,
  135.                                 unsigned flags );
  136.  
  137.    void (*fence)( struct pb_buffer *buf,
  138.                   struct pipe_fence_handle *fence );
  139.  
  140.    /**
  141.     * Get the base buffer and the offset.
  142.     *
  143.     * A buffer can be subdivided in smaller buffers. This method should return
  144.     * the underlaying buffer, and the relative offset.
  145.     *
  146.     * Buffers without an underlaying base buffer should return themselves, with
  147.     * a zero offset.
  148.     *
  149.     * Note that this will increase the reference count of the base buffer.
  150.     */
  151.    void (*get_base_buffer)( struct pb_buffer *buf,
  152.                             struct pb_buffer **base_buf,
  153.                             pb_size *offset );
  154.    
  155. };
  156.  
  157.  
  158.  
  159. /* Accessor functions for pb->vtbl:
  160.  */
  161. static INLINE void *
  162. pb_map(struct pb_buffer *buf,
  163.        unsigned flags, void *flush_ctx)
  164. {
  165.    assert(buf);
  166.    if(!buf)
  167.       return NULL;
  168.    assert(pipe_is_referenced(&buf->reference));
  169.    return buf->vtbl->map(buf, flags, flush_ctx);
  170. }
  171.  
  172.  
  173. static INLINE void
  174. pb_unmap(struct pb_buffer *buf)
  175. {
  176.    assert(buf);
  177.    if(!buf)
  178.       return;
  179.    assert(pipe_is_referenced(&buf->reference));
  180.    buf->vtbl->unmap(buf);
  181. }
  182.  
  183.  
  184. static INLINE void
  185. pb_get_base_buffer( struct pb_buffer *buf,
  186.                     struct pb_buffer **base_buf,
  187.                     pb_size *offset )
  188. {
  189.    assert(buf);
  190.    if(!buf) {
  191.       base_buf = NULL;
  192.       offset = 0;
  193.       return;
  194.    }
  195.    assert(pipe_is_referenced(&buf->reference));
  196.    assert(buf->vtbl->get_base_buffer);
  197.    buf->vtbl->get_base_buffer(buf, base_buf, offset);
  198.    assert(*base_buf);
  199.    assert(*offset < (*base_buf)->size);
  200. }
  201.  
  202.  
  203. static INLINE enum pipe_error
  204. pb_validate(struct pb_buffer *buf, struct pb_validate *vl, unsigned flags)
  205. {
  206.    assert(buf);
  207.    if(!buf)
  208.       return PIPE_ERROR;
  209.    assert(buf->vtbl->validate);
  210.    return buf->vtbl->validate(buf, vl, flags);
  211. }
  212.  
  213.  
  214. static INLINE void
  215. pb_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence)
  216. {
  217.    assert(buf);
  218.    if(!buf)
  219.       return;
  220.    assert(buf->vtbl->fence);
  221.    buf->vtbl->fence(buf, fence);
  222. }
  223.  
  224.  
  225. static INLINE void
  226. pb_destroy(struct pb_buffer *buf)
  227. {
  228.    assert(buf);
  229.    if(!buf)
  230.       return;
  231.    assert(!pipe_is_referenced(&buf->reference));
  232.    buf->vtbl->destroy(buf);
  233. }
  234.  
  235. static INLINE void
  236. pb_reference(struct pb_buffer **dst,
  237.              struct pb_buffer *src)
  238. {
  239.    struct pb_buffer *old = *dst;
  240.  
  241.    if (pipe_reference(&(*dst)->reference, &src->reference))
  242.       pb_destroy( old );
  243.    *dst = src;
  244. }
  245.  
  246.  
  247. /**
  248.  * Utility function to check whether the provided alignment is consistent with
  249.  * the requested or not.
  250.  */
  251. static INLINE boolean
  252. pb_check_alignment(pb_size requested, pb_size provided)
  253. {
  254.    if(!requested)
  255.       return TRUE;
  256.    if(requested > provided)
  257.       return FALSE;
  258.    if(provided % requested != 0)
  259.       return FALSE;
  260.    return TRUE;
  261. }
  262.  
  263.  
  264. /**
  265.  * Utility function to check whether the provided alignment is consistent with
  266.  * the requested or not.
  267.  */
  268. static INLINE boolean
  269. pb_check_usage(unsigned requested, unsigned provided)
  270. {
  271.    return (requested & provided) == requested ? TRUE : FALSE;
  272. }
  273.  
  274.  
  275. /**
  276.  * Malloc-based buffer to store data that can't be used by the graphics
  277.  * hardware.
  278.  */
  279. struct pb_buffer *
  280. pb_malloc_buffer_create(pb_size size,
  281.                         const struct pb_desc *desc);
  282.  
  283.  
  284. #ifdef __cplusplus
  285. }
  286. #endif
  287.  
  288. #endif /*PB_BUFFER_H_*/
  289.