Merge remote branch 'upstream/gallium-0.1' into nouveau-gallium-0.1
[mesa.git] / src / gallium / include / pipe / p_inlines.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 #ifndef P_INLINES_H
29 #define P_INLINES_H
30
31 #include "p_context.h"
32 #include "p_defines.h"
33 #include "p_screen.h"
34 #include "p_winsys.h"
35
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41
42 /* XXX: these are a kludge. will fix when all surfaces are views into
43 * textures, and free-floating winsys surfaces go away.
44 */
45 static INLINE void *
46 pipe_surface_map( struct pipe_surface *surf, unsigned flags )
47 {
48 if (surf->texture) {
49 struct pipe_screen *screen = surf->texture->screen;
50 return surf->texture->screen->surface_map( screen, surf, flags );
51 }
52 else {
53 struct pipe_winsys *winsys = surf->winsys;
54 char *map = (char *)winsys->buffer_map( winsys, surf->buffer, flags );
55 if (map == NULL)
56 return NULL;
57 return (void *)(map + surf->offset);
58 }
59 }
60
61 static INLINE void
62 pipe_surface_unmap( struct pipe_surface *surf )
63 {
64 if (surf->texture) {
65 struct pipe_screen *screen = surf->texture->screen;
66 surf->texture->screen->surface_unmap( screen, surf );
67 }
68 else {
69 struct pipe_winsys *winsys = surf->winsys;
70 winsys->buffer_unmap( winsys, surf->buffer );
71 }
72 }
73
74
75
76 /**
77 * Set 'ptr' to point to 'surf' and update reference counting.
78 * The old thing pointed to, if any, will be unreferenced first.
79 * 'surf' may be NULL.
80 */
81 static INLINE void
82 pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
83 {
84 /* bump the refcount first */
85 if (surf)
86 surf->refcount++;
87
88 if (*ptr) {
89
90 /* There are currently two sorts of surfaces... This needs to be
91 * fixed so that all surfaces are views into a texture.
92 */
93 if ((*ptr)->texture) {
94 struct pipe_screen *screen = (*ptr)->texture->screen;
95 screen->tex_surface_release( screen, ptr );
96 }
97 else {
98 struct pipe_winsys *winsys = (*ptr)->winsys;
99 winsys->surface_release(winsys, ptr);
100 }
101
102 assert(!*ptr);
103 }
104
105 *ptr = surf;
106 }
107
108
109 /* XXX: thread safety issues!
110 */
111 static INLINE void
112 pipe_buffer_reference(struct pipe_winsys *winsys,
113 struct pipe_buffer **ptr,
114 struct pipe_buffer *buf)
115 {
116 if (buf)
117 buf->refcount++;
118
119 if (*ptr && --(*ptr)->refcount == 0)
120 winsys->buffer_destroy( winsys, *ptr );
121
122 *ptr = buf;
123 }
124
125
126
127 /**
128 * \sa pipe_surface_reference
129 */
130 static INLINE void
131 pipe_texture_reference(struct pipe_texture **ptr,
132 struct pipe_texture *pt)
133 {
134 assert(ptr);
135
136 if (pt)
137 pt->refcount++;
138
139 if (*ptr) {
140 struct pipe_screen *screen = (*ptr)->screen;
141 assert(screen);
142 screen->texture_release(screen, ptr);
143
144 assert(!*ptr);
145 }
146
147 *ptr = pt;
148 }
149
150
151 static INLINE void
152 pipe_texture_release(struct pipe_texture **ptr)
153 {
154 struct pipe_screen *screen;
155 assert(ptr);
156 screen = (*ptr)->screen;
157 screen->texture_release(screen, ptr);
158 *ptr = NULL;
159 }
160
161
162 /**
163 * Convenience wrappers for winsys buffer functions.
164 */
165
166 static INLINE struct pipe_buffer *
167 pipe_buffer_create( struct pipe_context *pipe,
168 unsigned alignment, unsigned usage, unsigned size )
169 {
170 return pipe->winsys->buffer_create(pipe->winsys, alignment, usage, size);
171 }
172
173 static INLINE struct pipe_buffer *
174 pipe_user_buffer_create( struct pipe_context *pipe, void *ptr, unsigned size )
175 {
176 return pipe->winsys->user_buffer_create(pipe->winsys, ptr, size);
177 }
178
179 static INLINE void
180 pipe_buffer_destroy( struct pipe_context *pipe, struct pipe_buffer *buf )
181 {
182 pipe->winsys->buffer_destroy(pipe->winsys, buf);
183 }
184
185 static INLINE void *
186 pipe_buffer_map(struct pipe_context *pipe,
187 struct pipe_buffer *buf,
188 unsigned usage)
189 {
190 return pipe->winsys->buffer_map(pipe->winsys, buf, usage);
191 }
192
193 static INLINE void
194 pipe_buffer_unmap(struct pipe_context *pipe,
195 struct pipe_buffer *buf)
196 {
197 pipe->winsys->buffer_unmap(pipe->winsys, buf);
198 }
199
200 /* XXX when we're using this everywhere, get rid of
201 * pipe_buffer_reference() above.
202 */
203 static INLINE void
204 pipe_reference_buffer(struct pipe_context *pipe,
205 struct pipe_buffer **ptr,
206 struct pipe_buffer *buf)
207 {
208 pipe_buffer_reference(pipe->winsys, ptr, buf);
209 }
210
211
212 #ifdef __cplusplus
213 }
214 #endif
215
216 #endif /* P_INLINES_H */