xref: /aosp_15_r20/external/mesa3d/src/mesa/main/bufferobj.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23  * OTHER DEALINGS IN THE SOFTWARE.
24  */
25 
26 
27 
28 #ifndef BUFFEROBJ_H
29 #define BUFFEROBJ_H
30 
31 #include <stdbool.h>
32 #include "mtypes.h"
33 
34 
35 /*
36  * Internal functions
37  */
38 
39 static ALWAYS_INLINE struct pipe_resource *
_mesa_get_bufferobj_reference(struct gl_context * ctx,struct gl_buffer_object * obj)40 _mesa_get_bufferobj_reference(struct gl_context *ctx, struct gl_buffer_object *obj)
41 {
42    assert(obj);
43    struct pipe_resource *buffer = obj->buffer;
44 
45    /* Only one context is using the fast path. All other contexts must use
46     * the slow path.
47     */
48    if (unlikely(obj->private_refcount_ctx != ctx ||
49                 obj->private_refcount <= 0)) {
50       if (buffer) {
51          if (obj->private_refcount_ctx != ctx) {
52             p_atomic_inc(&buffer->reference.count);
53          } else {
54             /* This is the number of atomic increments we will skip. */
55             const unsigned count = 100000000;
56             p_atomic_add(&buffer->reference.count, count);
57 
58             /* Remove the reference that we return. */
59             assert(obj->private_refcount == 0);
60             obj->private_refcount = count - 1;
61          }
62       }
63       return buffer;
64    }
65 
66    /* Return a buffer reference while decrementing the private refcount.
67     * The buffer must be non-NULL, which is implied by private_refcount_ctx
68     * being non-NULL.
69     */
70    assert(buffer);
71    obj->private_refcount--;
72    return buffer;
73 }
74 
75 void _mesa_bufferobj_subdata(struct gl_context *ctx,
76                           GLintptrARB offset,
77                           GLsizeiptrARB size,
78                           const void * data, struct gl_buffer_object *obj);
79 GLboolean _mesa_bufferobj_data(struct gl_context *ctx,
80                             GLenum target,
81                             GLsizeiptrARB size,
82                             const void *data,
83                             GLenum usage,
84                             GLbitfield storageFlags,
85                             struct gl_buffer_object *obj);
86 void
87 _mesa_bufferobj_get_subdata(struct gl_context *ctx,
88                             GLintptrARB offset,
89                             GLsizeiptrARB size,
90                             void *data, struct gl_buffer_object *obj);
91 
92 void *_mesa_bufferobj_map_range(struct gl_context *ctx,
93                                 GLintptr offset, GLsizeiptr length,
94                                 GLbitfield access,
95                                 struct gl_buffer_object *obj,
96                                 gl_map_buffer_index index);
97 
98 void _mesa_bufferobj_flush_mapped_range(struct gl_context *ctx,
99                                         GLintptr offset, GLsizeiptr length,
100                                         struct gl_buffer_object *obj,
101                                         gl_map_buffer_index index);
102 GLboolean _mesa_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj,
103                                  gl_map_buffer_index index);
104 
105 struct gl_buffer_object *
106 _mesa_bufferobj_alloc(struct gl_context *ctx, GLuint id);
107 void
108 _mesa_bufferobj_release_buffer(struct gl_buffer_object *obj);
109 
110 enum pipe_map_flags
111 _mesa_access_flags_to_transfer_flags(GLbitfield access, bool wholeBuffer);
112 
113 /** Is the given buffer object currently mapped by the GL user? */
114 static inline GLboolean
_mesa_bufferobj_mapped(const struct gl_buffer_object * obj,gl_map_buffer_index index)115 _mesa_bufferobj_mapped(const struct gl_buffer_object *obj,
116                        gl_map_buffer_index index)
117 {
118    return obj->Mappings[index].Pointer != NULL;
119 }
120 
121 /**
122  * Check whether the given buffer object is illegally mapped prior to
123  * drawing from (or reading back to) the buffer.
124  * Note that it's legal for a buffer to be mapped at draw/readback time
125  * if it was mapped persistently (See GL_ARB_buffer_storage spec).
126  * \return true if the buffer is illegally mapped, false otherwise
127  */
128 static inline bool
_mesa_check_disallowed_mapping(const struct gl_buffer_object * obj)129 _mesa_check_disallowed_mapping(const struct gl_buffer_object *obj)
130 {
131    return _mesa_bufferobj_mapped(obj, MAP_USER) &&
132           !(obj->Mappings[MAP_USER].AccessFlags &
133             GL_MAP_PERSISTENT_BIT);
134 }
135 
136 
137 extern void
138 _mesa_init_buffer_objects(struct gl_context *ctx);
139 
140 extern void
141 _mesa_free_buffer_objects(struct gl_context *ctx);
142 
143 extern bool
144 _mesa_handle_bind_buffer_gen(struct gl_context *ctx,
145                              GLuint buffer,
146                              struct gl_buffer_object **buf_handle,
147                              const char *caller, bool no_error);
148 
149 extern void
150 _mesa_update_default_objects_buffer_objects(struct gl_context *ctx);
151 
152 
153 extern struct gl_buffer_object *
154 _mesa_lookup_bufferobj(struct gl_context *ctx, GLuint buffer);
155 
156 extern struct gl_buffer_object *
157 _mesa_lookup_bufferobj_locked(struct gl_context *ctx, GLuint buffer);
158 
159 extern struct gl_buffer_object *
160 _mesa_lookup_bufferobj_err(struct gl_context *ctx, GLuint buffer,
161                            const char *caller);
162 
163 extern struct gl_buffer_object *
164 _mesa_multi_bind_lookup_bufferobj(struct gl_context *ctx,
165                                   const GLuint *buffers,
166                                   GLuint index, const char *caller,
167                                   bool *error);
168 
169 extern void
170 _mesa_delete_buffer_object(struct gl_context *ctx,
171                            struct gl_buffer_object *bufObj);
172 
173 /**
174  * Set ptr to bufObj w/ reference counting.
175  * This is normally only called from the _mesa_reference_buffer_object() macro
176  * when there's a real pointer change.
177  */
178 static inline void
_mesa_reference_buffer_object_(struct gl_context * ctx,struct gl_buffer_object ** ptr,struct gl_buffer_object * bufObj,bool shared_binding)179 _mesa_reference_buffer_object_(struct gl_context *ctx,
180                                struct gl_buffer_object **ptr,
181                                struct gl_buffer_object *bufObj,
182                                bool shared_binding)
183 {
184    if (*ptr) {
185       /* Unreference the old buffer */
186       struct gl_buffer_object *oldObj = *ptr;
187 
188       assert(oldObj->RefCount >= 1);
189 
190       /* Count references only if the context doesn't own the buffer or if
191        * ptr is a binding point shared by multiple contexts (such as a texture
192        * buffer object being a buffer bound within a texture object).
193        */
194       if (shared_binding || ctx != oldObj->Ctx) {
195          if (p_atomic_dec_zero(&oldObj->RefCount)) {
196             _mesa_delete_buffer_object(ctx, oldObj);
197          }
198       } else {
199          /* Update the private ref count. */
200          assert(oldObj->CtxRefCount >= 1);
201          oldObj->CtxRefCount--;
202       }
203    }
204 
205    if (bufObj) {
206       /* reference new buffer */
207       if (shared_binding || ctx != bufObj->Ctx)
208          p_atomic_inc(&bufObj->RefCount);
209       else
210          bufObj->CtxRefCount++;
211    }
212 
213    *ptr = bufObj;
214 }
215 
216 /**
217  * Assign a buffer into a pointer with reference counting. The destination
218  * must be private within a context.
219  */
220 static inline void
_mesa_reference_buffer_object(struct gl_context * ctx,struct gl_buffer_object ** ptr,struct gl_buffer_object * bufObj)221 _mesa_reference_buffer_object(struct gl_context *ctx,
222                               struct gl_buffer_object **ptr,
223                               struct gl_buffer_object *bufObj)
224 {
225    if (*ptr != bufObj)
226       _mesa_reference_buffer_object_(ctx, ptr, bufObj, false);
227 }
228 
229 /**
230  * Assign a buffer into a pointer with reference counting. The destination
231  * must be shareable among multiple contexts.
232  */
233 static inline void
_mesa_reference_buffer_object_shared(struct gl_context * ctx,struct gl_buffer_object ** ptr,struct gl_buffer_object * bufObj)234 _mesa_reference_buffer_object_shared(struct gl_context *ctx,
235                                      struct gl_buffer_object **ptr,
236                                      struct gl_buffer_object *bufObj)
237 {
238    if (*ptr != bufObj)
239       _mesa_reference_buffer_object_(ctx, ptr, bufObj, true);
240 }
241 
242 extern void
243 _mesa_buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
244                   GLenum target, GLsizeiptr size, const GLvoid *data,
245                   GLenum usage, const char *func);
246 
247 extern void
248 _mesa_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
249                       GLintptr offset, GLsizeiptr size, const GLvoid *data);
250 
251 extern void
252 _mesa_buffer_unmap_all_mappings(struct gl_context *ctx,
253                                 struct gl_buffer_object *bufObj);
254 
255 extern void
256 _mesa_ClearBufferSubData_sw(struct gl_context *ctx,
257                             GLintptr offset, GLsizeiptr size,
258                             const GLvoid *clearValue,
259                             GLsizeiptr clearValueSize,
260                             struct gl_buffer_object *bufObj);
261 
262 #endif
263