Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / auxiliary / pipebuffer / pb_buffer.h
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    /* This used to be a pipe_buffer struct:
101     */
102    struct {
103       struct pipe_reference  reference;
104       unsigned               size;
105       unsigned               alignment;
106       unsigned               usage;
107    } base;
108
109    /**
110     * Pointer to the virtual function table.
111     *
112     * Avoid accessing this table directly. Use the inline functions below 
113     * instead to avoid mistakes. 
114     */
115    const struct pb_vtbl *vtbl;
116 };
117
118
119 /**
120  * Virtual function table for the buffer storage operations.
121  * 
122  * Note that creation is not done through this table.
123  */
124 struct pb_vtbl
125 {
126    void (*destroy)( struct pb_buffer *buf );
127
128    /** 
129     * Map the entire data store of a buffer object into the client's address.
130     * flags is bitmask of PB_USAGE_CPU_READ/WRITE. 
131     */
132    void *(*map)( struct pb_buffer *buf, 
133                  unsigned flags, void *flush_ctx );
134    
135    void (*unmap)( struct pb_buffer *buf );
136
137    enum pipe_error (*validate)( struct pb_buffer *buf, 
138                                 struct pb_validate *vl,
139                                 unsigned flags );
140
141    void (*fence)( struct pb_buffer *buf, 
142                   struct pipe_fence_handle *fence );
143
144    /**
145     * Get the base buffer and the offset.
146     * 
147     * A buffer can be subdivided in smaller buffers. This method should return
148     * the underlaying buffer, and the relative offset.
149     * 
150     * Buffers without an underlaying base buffer should return themselves, with 
151     * a zero offset.
152     * 
153     * Note that this will increase the reference count of the base buffer.
154     */
155    void (*get_base_buffer)( struct pb_buffer *buf,
156                             struct pb_buffer **base_buf,
157                             pb_size *offset );
158    
159 };
160
161
162
163 /* Accessor functions for pb->vtbl:
164  */
165 static INLINE void *
166 pb_map(struct pb_buffer *buf, 
167        unsigned flags, void *flush_ctx)
168 {
169    assert(buf);
170    if(!buf)
171       return NULL;
172    assert(pipe_is_referenced(&buf->base.reference));
173    return buf->vtbl->map(buf, flags, flush_ctx);
174 }
175
176
177 static INLINE void 
178 pb_unmap(struct pb_buffer *buf)
179 {
180    assert(buf);
181    if(!buf)
182       return;
183    assert(pipe_is_referenced(&buf->base.reference));
184    buf->vtbl->unmap(buf);
185 }
186
187
188 static INLINE void
189 pb_get_base_buffer( struct pb_buffer *buf,
190                     struct pb_buffer **base_buf,
191                     pb_size *offset )
192 {
193    assert(buf);
194    if(!buf) {
195       base_buf = NULL;
196       offset = 0;
197       return;
198    }
199    assert(pipe_is_referenced(&buf->base.reference));
200    assert(buf->vtbl->get_base_buffer);
201    buf->vtbl->get_base_buffer(buf, base_buf, offset);
202    assert(*base_buf);
203    assert(*offset < (*base_buf)->base.size);
204 }
205
206
207 static INLINE enum pipe_error 
208 pb_validate(struct pb_buffer *buf, struct pb_validate *vl, unsigned flags)
209 {
210    assert(buf);
211    if(!buf)
212       return PIPE_ERROR;
213    assert(buf->vtbl->validate);
214    return buf->vtbl->validate(buf, vl, flags);
215 }
216
217
218 static INLINE void 
219 pb_fence(struct pb_buffer *buf, struct pipe_fence_handle *fence)
220 {
221    assert(buf);
222    if(!buf)
223       return;
224    assert(buf->vtbl->fence);
225    buf->vtbl->fence(buf, fence);
226 }
227
228
229 static INLINE void 
230 pb_destroy(struct pb_buffer *buf)
231 {
232    assert(buf);
233    if(!buf)
234       return;
235    assert(!pipe_is_referenced(&buf->base.reference));
236    buf->vtbl->destroy(buf);
237 }
238
239 static INLINE void
240 pb_reference(struct pb_buffer **dst,
241              struct pb_buffer *src)
242 {
243    struct pb_buffer *old = *dst;
244
245    if (pipe_reference(&(*dst)->base.reference, &src->base.reference))
246       pb_destroy( old );
247    *dst = src;
248 }
249
250
251 /**
252  * Utility function to check whether the provided alignment is consistent with
253  * the requested or not.
254  */
255 static INLINE boolean
256 pb_check_alignment(pb_size requested, pb_size provided)
257 {
258    if(!requested)
259       return TRUE;
260    if(requested > provided)
261       return FALSE;
262    if(provided % requested != 0)
263       return FALSE;
264    return TRUE;
265 }
266
267
268 /**
269  * Utility function to check whether the provided alignment is consistent with
270  * the requested or not.
271  */
272 static INLINE boolean
273 pb_check_usage(unsigned requested, unsigned provided)
274 {
275    return (requested & provided) == requested ? TRUE : FALSE;
276 }
277
278
279 /**
280  * Malloc-based buffer to store data that can't be used by the graphics 
281  * hardware.
282  */
283 struct pb_buffer *
284 pb_malloc_buffer_create(pb_size size, 
285                         const struct pb_desc *desc);
286
287
288 #ifdef __cplusplus
289 }
290 #endif
291
292 #endif /*PB_BUFFER_H_*/