1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker *
7*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
9*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
10*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
12*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included
15*61046927SAndroid Build Coastguard Worker * in all copies or substantial portions of the Software.
16*61046927SAndroid Build Coastguard Worker *
17*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18*61046927SAndroid Build Coastguard Worker * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21*61046927SAndroid Build Coastguard Worker * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22*61046927SAndroid Build Coastguard Worker * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23*61046927SAndroid Build Coastguard Worker * OTHER DEALINGS IN THE SOFTWARE.
24*61046927SAndroid Build Coastguard Worker */
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker
27*61046927SAndroid Build Coastguard Worker /**
28*61046927SAndroid Build Coastguard Worker * \file bufferobj.c
29*61046927SAndroid Build Coastguard Worker * \brief Functions for the GL_ARB_vertex/pixel_buffer_object extensions.
30*61046927SAndroid Build Coastguard Worker * \author Brian Paul, Ian Romanick
31*61046927SAndroid Build Coastguard Worker */
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
34*61046927SAndroid Build Coastguard Worker #include <inttypes.h> /* for PRId64 macro */
35*61046927SAndroid Build Coastguard Worker #include "util/u_debug.h"
36*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
37*61046927SAndroid Build Coastguard Worker #include "enums.h"
38*61046927SAndroid Build Coastguard Worker #include "hash.h"
39*61046927SAndroid Build Coastguard Worker #include "context.h"
40*61046927SAndroid Build Coastguard Worker #include "bufferobj.h"
41*61046927SAndroid Build Coastguard Worker #include "externalobjects.h"
42*61046927SAndroid Build Coastguard Worker #include "mtypes.h"
43*61046927SAndroid Build Coastguard Worker #include "teximage.h"
44*61046927SAndroid Build Coastguard Worker #include "glformats.h"
45*61046927SAndroid Build Coastguard Worker #include "texstore.h"
46*61046927SAndroid Build Coastguard Worker #include "transformfeedback.h"
47*61046927SAndroid Build Coastguard Worker #include "varray.h"
48*61046927SAndroid Build Coastguard Worker #include "util/u_atomic.h"
49*61046927SAndroid Build Coastguard Worker #include "util/u_memory.h"
50*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
51*61046927SAndroid Build Coastguard Worker #include "util/set.h"
52*61046927SAndroid Build Coastguard Worker
53*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_debug.h"
54*61046927SAndroid Build Coastguard Worker #include "state_tracker/st_atom.h"
55*61046927SAndroid Build Coastguard Worker #include "frontend/api.h"
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker #include "util/u_inlines.h"
58*61046927SAndroid Build Coastguard Worker /* Debug flags */
59*61046927SAndroid Build Coastguard Worker /*#define VBO_DEBUG*/
60*61046927SAndroid Build Coastguard Worker /*#define BOUNDS_CHECK*/
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker
63*61046927SAndroid Build Coastguard Worker /**
64*61046927SAndroid Build Coastguard Worker * We count the number of buffer modification calls to check for
65*61046927SAndroid Build Coastguard Worker * inefficient buffer use. This is the number of such calls before we
66*61046927SAndroid Build Coastguard Worker * issue a warning.
67*61046927SAndroid Build Coastguard Worker */
68*61046927SAndroid Build Coastguard Worker #define BUFFER_WARNING_CALL_COUNT 4
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker
71*61046927SAndroid Build Coastguard Worker /**
72*61046927SAndroid Build Coastguard Worker * Replace data in a subrange of buffer object. If the data range
73*61046927SAndroid Build Coastguard Worker * specified by size + offset extends beyond the end of the buffer or
74*61046927SAndroid Build Coastguard Worker * if data is NULL, no copy is performed.
75*61046927SAndroid Build Coastguard Worker * Called via glBufferSubDataARB().
76*61046927SAndroid Build Coastguard Worker */
77*61046927SAndroid Build Coastguard Worker void
_mesa_bufferobj_subdata(struct gl_context * ctx,GLintptrARB offset,GLsizeiptrARB size,const void * data,struct gl_buffer_object * obj)78*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_subdata(struct gl_context *ctx,
79*61046927SAndroid Build Coastguard Worker GLintptrARB offset,
80*61046927SAndroid Build Coastguard Worker GLsizeiptrARB size,
81*61046927SAndroid Build Coastguard Worker const void *data, struct gl_buffer_object *obj)
82*61046927SAndroid Build Coastguard Worker {
83*61046927SAndroid Build Coastguard Worker /* we may be called from VBO code, so double-check params here */
84*61046927SAndroid Build Coastguard Worker assert(offset >= 0);
85*61046927SAndroid Build Coastguard Worker assert(size >= 0);
86*61046927SAndroid Build Coastguard Worker assert(offset + size <= obj->Size);
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker if (!size)
89*61046927SAndroid Build Coastguard Worker return;
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker /*
92*61046927SAndroid Build Coastguard Worker * According to ARB_vertex_buffer_object specification, if data is null,
93*61046927SAndroid Build Coastguard Worker * then the contents of the buffer object's data store is undefined. We just
94*61046927SAndroid Build Coastguard Worker * ignore, and leave it unchanged.
95*61046927SAndroid Build Coastguard Worker */
96*61046927SAndroid Build Coastguard Worker if (!data)
97*61046927SAndroid Build Coastguard Worker return;
98*61046927SAndroid Build Coastguard Worker
99*61046927SAndroid Build Coastguard Worker if (!obj->buffer) {
100*61046927SAndroid Build Coastguard Worker /* we probably ran out of memory during buffer allocation */
101*61046927SAndroid Build Coastguard Worker return;
102*61046927SAndroid Build Coastguard Worker }
103*61046927SAndroid Build Coastguard Worker
104*61046927SAndroid Build Coastguard Worker /* Now that transfers are per-context, we don't have to figure out
105*61046927SAndroid Build Coastguard Worker * flushing here. Usually drivers won't need to flush in this case
106*61046927SAndroid Build Coastguard Worker * even if the buffer is currently referenced by hardware - they
107*61046927SAndroid Build Coastguard Worker * just queue the upload as dma rather than mapping the underlying
108*61046927SAndroid Build Coastguard Worker * buffer directly.
109*61046927SAndroid Build Coastguard Worker *
110*61046927SAndroid Build Coastguard Worker * If the buffer is mapped, suppress implicit buffer range invalidation
111*61046927SAndroid Build Coastguard Worker * by using PIPE_MAP_DIRECTLY.
112*61046927SAndroid Build Coastguard Worker */
113*61046927SAndroid Build Coastguard Worker struct pipe_context *pipe = ctx->pipe;
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker pipe->buffer_subdata(pipe, obj->buffer,
116*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_mapped(obj, MAP_USER) ?
117*61046927SAndroid Build Coastguard Worker PIPE_MAP_DIRECTLY : 0,
118*61046927SAndroid Build Coastguard Worker offset, size, data);
119*61046927SAndroid Build Coastguard Worker }
120*61046927SAndroid Build Coastguard Worker
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Worker /**
123*61046927SAndroid Build Coastguard Worker * Called via glGetBufferSubDataARB().
124*61046927SAndroid Build Coastguard Worker */
125*61046927SAndroid Build Coastguard Worker static void
bufferobj_get_subdata(struct gl_context * ctx,GLintptrARB offset,GLsizeiptrARB size,void * data,struct gl_buffer_object * obj)126*61046927SAndroid Build Coastguard Worker bufferobj_get_subdata(struct gl_context *ctx,
127*61046927SAndroid Build Coastguard Worker GLintptrARB offset,
128*61046927SAndroid Build Coastguard Worker GLsizeiptrARB size,
129*61046927SAndroid Build Coastguard Worker void *data, struct gl_buffer_object *obj)
130*61046927SAndroid Build Coastguard Worker {
131*61046927SAndroid Build Coastguard Worker /* we may be called from VBO code, so double-check params here */
132*61046927SAndroid Build Coastguard Worker assert(offset >= 0);
133*61046927SAndroid Build Coastguard Worker assert(size >= 0);
134*61046927SAndroid Build Coastguard Worker assert(offset + size <= obj->Size);
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker if (!size)
137*61046927SAndroid Build Coastguard Worker return;
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker if (!obj->buffer) {
140*61046927SAndroid Build Coastguard Worker /* we probably ran out of memory during buffer allocation */
141*61046927SAndroid Build Coastguard Worker return;
142*61046927SAndroid Build Coastguard Worker }
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker pipe_buffer_read(ctx->pipe, obj->buffer,
145*61046927SAndroid Build Coastguard Worker offset, size, data);
146*61046927SAndroid Build Coastguard Worker }
147*61046927SAndroid Build Coastguard Worker
148*61046927SAndroid Build Coastguard Worker void
_mesa_bufferobj_get_subdata(struct gl_context * ctx,GLintptrARB offset,GLsizeiptrARB size,void * data,struct gl_buffer_object * obj)149*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_get_subdata(struct gl_context *ctx,
150*61046927SAndroid Build Coastguard Worker GLintptrARB offset,
151*61046927SAndroid Build Coastguard Worker GLsizeiptrARB size,
152*61046927SAndroid Build Coastguard Worker void *data, struct gl_buffer_object *obj)
153*61046927SAndroid Build Coastguard Worker {
154*61046927SAndroid Build Coastguard Worker bufferobj_get_subdata(ctx, offset, size, data, obj);
155*61046927SAndroid Build Coastguard Worker }
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker /**
158*61046927SAndroid Build Coastguard Worker * Return bitmask of PIPE_BIND_x flags corresponding a GL buffer target.
159*61046927SAndroid Build Coastguard Worker */
160*61046927SAndroid Build Coastguard Worker static unsigned
buffer_target_to_bind_flags(GLenum target)161*61046927SAndroid Build Coastguard Worker buffer_target_to_bind_flags(GLenum target)
162*61046927SAndroid Build Coastguard Worker {
163*61046927SAndroid Build Coastguard Worker switch (target) {
164*61046927SAndroid Build Coastguard Worker case GL_PIXEL_PACK_BUFFER_ARB:
165*61046927SAndroid Build Coastguard Worker case GL_PIXEL_UNPACK_BUFFER_ARB:
166*61046927SAndroid Build Coastguard Worker return PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW;
167*61046927SAndroid Build Coastguard Worker case GL_ARRAY_BUFFER_ARB:
168*61046927SAndroid Build Coastguard Worker return PIPE_BIND_VERTEX_BUFFER;
169*61046927SAndroid Build Coastguard Worker case GL_ELEMENT_ARRAY_BUFFER_ARB:
170*61046927SAndroid Build Coastguard Worker return PIPE_BIND_INDEX_BUFFER;
171*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_BUFFER:
172*61046927SAndroid Build Coastguard Worker return PIPE_BIND_SAMPLER_VIEW;
173*61046927SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_BUFFER:
174*61046927SAndroid Build Coastguard Worker return PIPE_BIND_STREAM_OUTPUT;
175*61046927SAndroid Build Coastguard Worker case GL_UNIFORM_BUFFER:
176*61046927SAndroid Build Coastguard Worker return PIPE_BIND_CONSTANT_BUFFER;
177*61046927SAndroid Build Coastguard Worker case GL_DRAW_INDIRECT_BUFFER:
178*61046927SAndroid Build Coastguard Worker case GL_PARAMETER_BUFFER_ARB:
179*61046927SAndroid Build Coastguard Worker return PIPE_BIND_COMMAND_ARGS_BUFFER;
180*61046927SAndroid Build Coastguard Worker case GL_ATOMIC_COUNTER_BUFFER:
181*61046927SAndroid Build Coastguard Worker case GL_SHADER_STORAGE_BUFFER:
182*61046927SAndroid Build Coastguard Worker return PIPE_BIND_SHADER_BUFFER;
183*61046927SAndroid Build Coastguard Worker case GL_QUERY_BUFFER:
184*61046927SAndroid Build Coastguard Worker return PIPE_BIND_QUERY_BUFFER;
185*61046927SAndroid Build Coastguard Worker default:
186*61046927SAndroid Build Coastguard Worker return 0;
187*61046927SAndroid Build Coastguard Worker }
188*61046927SAndroid Build Coastguard Worker }
189*61046927SAndroid Build Coastguard Worker
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker /**
192*61046927SAndroid Build Coastguard Worker * Return bitmask of PIPE_RESOURCE_x flags corresponding to GL_MAP_x flags.
193*61046927SAndroid Build Coastguard Worker */
194*61046927SAndroid Build Coastguard Worker static unsigned
storage_flags_to_buffer_flags(GLbitfield storageFlags)195*61046927SAndroid Build Coastguard Worker storage_flags_to_buffer_flags(GLbitfield storageFlags)
196*61046927SAndroid Build Coastguard Worker {
197*61046927SAndroid Build Coastguard Worker unsigned flags = 0;
198*61046927SAndroid Build Coastguard Worker if (storageFlags & GL_MAP_PERSISTENT_BIT)
199*61046927SAndroid Build Coastguard Worker flags |= PIPE_RESOURCE_FLAG_MAP_PERSISTENT;
200*61046927SAndroid Build Coastguard Worker if (storageFlags & GL_MAP_COHERENT_BIT)
201*61046927SAndroid Build Coastguard Worker flags |= PIPE_RESOURCE_FLAG_MAP_COHERENT;
202*61046927SAndroid Build Coastguard Worker if (storageFlags & GL_SPARSE_STORAGE_BIT_ARB)
203*61046927SAndroid Build Coastguard Worker flags |= PIPE_RESOURCE_FLAG_SPARSE;
204*61046927SAndroid Build Coastguard Worker return flags;
205*61046927SAndroid Build Coastguard Worker }
206*61046927SAndroid Build Coastguard Worker
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker /**
209*61046927SAndroid Build Coastguard Worker * From a buffer object's target, immutability flag, storage flags and
210*61046927SAndroid Build Coastguard Worker * usage hint, return a pipe_resource_usage value (PIPE_USAGE_DYNAMIC,
211*61046927SAndroid Build Coastguard Worker * STREAM, etc).
212*61046927SAndroid Build Coastguard Worker */
213*61046927SAndroid Build Coastguard Worker static enum pipe_resource_usage
buffer_usage(GLenum target,GLboolean immutable,GLbitfield storageFlags,GLenum usage)214*61046927SAndroid Build Coastguard Worker buffer_usage(GLenum target, GLboolean immutable,
215*61046927SAndroid Build Coastguard Worker GLbitfield storageFlags, GLenum usage)
216*61046927SAndroid Build Coastguard Worker {
217*61046927SAndroid Build Coastguard Worker /* "immutable" means that "storageFlags" was set by the user and "usage"
218*61046927SAndroid Build Coastguard Worker * was guessed by Mesa. Otherwise, "usage" was set by the user and
219*61046927SAndroid Build Coastguard Worker * storageFlags was guessed by Mesa.
220*61046927SAndroid Build Coastguard Worker *
221*61046927SAndroid Build Coastguard Worker * Therefore, use storageFlags with immutable, else use "usage".
222*61046927SAndroid Build Coastguard Worker */
223*61046927SAndroid Build Coastguard Worker if (immutable) {
224*61046927SAndroid Build Coastguard Worker /* BufferStorage */
225*61046927SAndroid Build Coastguard Worker if (storageFlags & GL_MAP_READ_BIT)
226*61046927SAndroid Build Coastguard Worker return PIPE_USAGE_STAGING;
227*61046927SAndroid Build Coastguard Worker else if (storageFlags & GL_CLIENT_STORAGE_BIT)
228*61046927SAndroid Build Coastguard Worker return PIPE_USAGE_STREAM;
229*61046927SAndroid Build Coastguard Worker else
230*61046927SAndroid Build Coastguard Worker return PIPE_USAGE_DEFAULT;
231*61046927SAndroid Build Coastguard Worker }
232*61046927SAndroid Build Coastguard Worker else {
233*61046927SAndroid Build Coastguard Worker /* These are often read by the CPU, so enable CPU caches. */
234*61046927SAndroid Build Coastguard Worker if (target == GL_PIXEL_PACK_BUFFER ||
235*61046927SAndroid Build Coastguard Worker target == GL_PIXEL_UNPACK_BUFFER)
236*61046927SAndroid Build Coastguard Worker return PIPE_USAGE_STAGING;
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker /* BufferData */
239*61046927SAndroid Build Coastguard Worker switch (usage) {
240*61046927SAndroid Build Coastguard Worker case GL_DYNAMIC_DRAW:
241*61046927SAndroid Build Coastguard Worker case GL_DYNAMIC_COPY:
242*61046927SAndroid Build Coastguard Worker return PIPE_USAGE_DYNAMIC;
243*61046927SAndroid Build Coastguard Worker case GL_STREAM_DRAW:
244*61046927SAndroid Build Coastguard Worker case GL_STREAM_COPY:
245*61046927SAndroid Build Coastguard Worker return PIPE_USAGE_STREAM;
246*61046927SAndroid Build Coastguard Worker case GL_STATIC_READ:
247*61046927SAndroid Build Coastguard Worker case GL_DYNAMIC_READ:
248*61046927SAndroid Build Coastguard Worker case GL_STREAM_READ:
249*61046927SAndroid Build Coastguard Worker return PIPE_USAGE_STAGING;
250*61046927SAndroid Build Coastguard Worker case GL_STATIC_DRAW:
251*61046927SAndroid Build Coastguard Worker case GL_STATIC_COPY:
252*61046927SAndroid Build Coastguard Worker default:
253*61046927SAndroid Build Coastguard Worker return PIPE_USAGE_DEFAULT;
254*61046927SAndroid Build Coastguard Worker }
255*61046927SAndroid Build Coastguard Worker }
256*61046927SAndroid Build Coastguard Worker }
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE GLboolean
bufferobj_data(struct gl_context * ctx,GLenum target,GLsizeiptrARB size,const void * data,struct gl_memory_object * memObj,GLuint64 offset,GLenum usage,GLbitfield storageFlags,struct gl_buffer_object * obj)260*61046927SAndroid Build Coastguard Worker bufferobj_data(struct gl_context *ctx,
261*61046927SAndroid Build Coastguard Worker GLenum target,
262*61046927SAndroid Build Coastguard Worker GLsizeiptrARB size,
263*61046927SAndroid Build Coastguard Worker const void *data,
264*61046927SAndroid Build Coastguard Worker struct gl_memory_object *memObj,
265*61046927SAndroid Build Coastguard Worker GLuint64 offset,
266*61046927SAndroid Build Coastguard Worker GLenum usage,
267*61046927SAndroid Build Coastguard Worker GLbitfield storageFlags,
268*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *obj)
269*61046927SAndroid Build Coastguard Worker {
270*61046927SAndroid Build Coastguard Worker struct pipe_context *pipe = ctx->pipe;
271*61046927SAndroid Build Coastguard Worker struct pipe_screen *screen = pipe->screen;
272*61046927SAndroid Build Coastguard Worker bool is_mapped = _mesa_bufferobj_mapped(obj, MAP_USER);
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker if (size > UINT32_MAX || offset > UINT32_MAX) {
275*61046927SAndroid Build Coastguard Worker /* pipe_resource.width0 is 32 bits only and increasing it
276*61046927SAndroid Build Coastguard Worker * to 64 bits doesn't make much sense since hw support
277*61046927SAndroid Build Coastguard Worker * for > 4GB resources is limited.
278*61046927SAndroid Build Coastguard Worker */
279*61046927SAndroid Build Coastguard Worker obj->Size = 0;
280*61046927SAndroid Build Coastguard Worker return GL_FALSE;
281*61046927SAndroid Build Coastguard Worker }
282*61046927SAndroid Build Coastguard Worker
283*61046927SAndroid Build Coastguard Worker if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD &&
284*61046927SAndroid Build Coastguard Worker size && obj->buffer &&
285*61046927SAndroid Build Coastguard Worker obj->Size == size &&
286*61046927SAndroid Build Coastguard Worker obj->Usage == usage &&
287*61046927SAndroid Build Coastguard Worker obj->StorageFlags == storageFlags) {
288*61046927SAndroid Build Coastguard Worker if (data) {
289*61046927SAndroid Build Coastguard Worker /* Just discard the old contents and write new data.
290*61046927SAndroid Build Coastguard Worker * This should be the same as creating a new buffer, but we avoid
291*61046927SAndroid Build Coastguard Worker * a lot of validation in Mesa.
292*61046927SAndroid Build Coastguard Worker *
293*61046927SAndroid Build Coastguard Worker * If the buffer is mapped, we can't discard it.
294*61046927SAndroid Build Coastguard Worker *
295*61046927SAndroid Build Coastguard Worker * PIPE_MAP_DIRECTLY supresses implicit buffer range
296*61046927SAndroid Build Coastguard Worker * invalidation.
297*61046927SAndroid Build Coastguard Worker */
298*61046927SAndroid Build Coastguard Worker pipe->buffer_subdata(pipe, obj->buffer,
299*61046927SAndroid Build Coastguard Worker is_mapped ? PIPE_MAP_DIRECTLY :
300*61046927SAndroid Build Coastguard Worker PIPE_MAP_DISCARD_WHOLE_RESOURCE,
301*61046927SAndroid Build Coastguard Worker 0, size, data);
302*61046927SAndroid Build Coastguard Worker return GL_TRUE;
303*61046927SAndroid Build Coastguard Worker } else if (is_mapped) {
304*61046927SAndroid Build Coastguard Worker return GL_TRUE; /* can't reallocate, nothing to do */
305*61046927SAndroid Build Coastguard Worker } else if (screen->get_param(screen, PIPE_CAP_INVALIDATE_BUFFER)) {
306*61046927SAndroid Build Coastguard Worker pipe->invalidate_resource(pipe, obj->buffer);
307*61046927SAndroid Build Coastguard Worker return GL_TRUE;
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker }
310*61046927SAndroid Build Coastguard Worker
311*61046927SAndroid Build Coastguard Worker obj->Size = size;
312*61046927SAndroid Build Coastguard Worker obj->Usage = usage;
313*61046927SAndroid Build Coastguard Worker obj->StorageFlags = storageFlags;
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_release_buffer(obj);
316*61046927SAndroid Build Coastguard Worker
317*61046927SAndroid Build Coastguard Worker unsigned bindings = buffer_target_to_bind_flags(target);
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker if (storageFlags & MESA_GALLIUM_VERTEX_STATE_STORAGE)
320*61046927SAndroid Build Coastguard Worker bindings |= PIPE_BIND_VERTEX_STATE;
321*61046927SAndroid Build Coastguard Worker
322*61046927SAndroid Build Coastguard Worker if (ST_DEBUG & DEBUG_BUFFER) {
323*61046927SAndroid Build Coastguard Worker debug_printf("Create buffer size %" PRId64 " bind 0x%x\n",
324*61046927SAndroid Build Coastguard Worker (int64_t) size, bindings);
325*61046927SAndroid Build Coastguard Worker }
326*61046927SAndroid Build Coastguard Worker
327*61046927SAndroid Build Coastguard Worker if (size != 0) {
328*61046927SAndroid Build Coastguard Worker struct pipe_resource buffer;
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker memset(&buffer, 0, sizeof buffer);
331*61046927SAndroid Build Coastguard Worker buffer.target = PIPE_BUFFER;
332*61046927SAndroid Build Coastguard Worker buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
333*61046927SAndroid Build Coastguard Worker buffer.bind = bindings;
334*61046927SAndroid Build Coastguard Worker buffer.usage =
335*61046927SAndroid Build Coastguard Worker buffer_usage(target, obj->Immutable, storageFlags, usage);
336*61046927SAndroid Build Coastguard Worker buffer.flags = storage_flags_to_buffer_flags(storageFlags);
337*61046927SAndroid Build Coastguard Worker buffer.width0 = size;
338*61046927SAndroid Build Coastguard Worker buffer.height0 = 1;
339*61046927SAndroid Build Coastguard Worker buffer.depth0 = 1;
340*61046927SAndroid Build Coastguard Worker buffer.array_size = 1;
341*61046927SAndroid Build Coastguard Worker
342*61046927SAndroid Build Coastguard Worker if (memObj) {
343*61046927SAndroid Build Coastguard Worker obj->buffer = screen->resource_from_memobj(screen, &buffer,
344*61046927SAndroid Build Coastguard Worker memObj->memory,
345*61046927SAndroid Build Coastguard Worker offset);
346*61046927SAndroid Build Coastguard Worker }
347*61046927SAndroid Build Coastguard Worker else if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
348*61046927SAndroid Build Coastguard Worker obj->buffer =
349*61046927SAndroid Build Coastguard Worker screen->resource_from_user_memory(screen, &buffer, (void*)data);
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker else {
352*61046927SAndroid Build Coastguard Worker obj->buffer = screen->resource_create(screen, &buffer);
353*61046927SAndroid Build Coastguard Worker
354*61046927SAndroid Build Coastguard Worker if (obj->buffer && data)
355*61046927SAndroid Build Coastguard Worker pipe_buffer_write(pipe, obj->buffer, 0, size, data);
356*61046927SAndroid Build Coastguard Worker }
357*61046927SAndroid Build Coastguard Worker
358*61046927SAndroid Build Coastguard Worker if (!obj->buffer) {
359*61046927SAndroid Build Coastguard Worker /* out of memory */
360*61046927SAndroid Build Coastguard Worker obj->Size = 0;
361*61046927SAndroid Build Coastguard Worker return GL_FALSE;
362*61046927SAndroid Build Coastguard Worker }
363*61046927SAndroid Build Coastguard Worker
364*61046927SAndroid Build Coastguard Worker obj->private_refcount_ctx = ctx;
365*61046927SAndroid Build Coastguard Worker }
366*61046927SAndroid Build Coastguard Worker
367*61046927SAndroid Build Coastguard Worker /* The current buffer may be bound, so we have to revalidate all atoms that
368*61046927SAndroid Build Coastguard Worker * might be using it.
369*61046927SAndroid Build Coastguard Worker */
370*61046927SAndroid Build Coastguard Worker if (obj->UsageHistory & USAGE_ARRAY_BUFFER)
371*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS;
372*61046927SAndroid Build Coastguard Worker if (obj->UsageHistory & USAGE_UNIFORM_BUFFER)
373*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_UNIFORM_BUFFER;
374*61046927SAndroid Build Coastguard Worker if (obj->UsageHistory & USAGE_SHADER_STORAGE_BUFFER)
375*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_STORAGE_BUFFER;
376*61046927SAndroid Build Coastguard Worker if (obj->UsageHistory & USAGE_TEXTURE_BUFFER)
377*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_SAMPLER_VIEWS | ST_NEW_IMAGE_UNITS;
378*61046927SAndroid Build Coastguard Worker if (obj->UsageHistory & USAGE_ATOMIC_COUNTER_BUFFER)
379*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer;
380*61046927SAndroid Build Coastguard Worker
381*61046927SAndroid Build Coastguard Worker return GL_TRUE;
382*61046927SAndroid Build Coastguard Worker }
383*61046927SAndroid Build Coastguard Worker
384*61046927SAndroid Build Coastguard Worker /**
385*61046927SAndroid Build Coastguard Worker * Allocate space for and store data in a buffer object. Any data that was
386*61046927SAndroid Build Coastguard Worker * previously stored in the buffer object is lost. If data is NULL,
387*61046927SAndroid Build Coastguard Worker * memory will be allocated, but no copy will occur.
388*61046927SAndroid Build Coastguard Worker * Called via ctx->Driver.BufferData().
389*61046927SAndroid Build Coastguard Worker * \return GL_TRUE for success, GL_FALSE if out of memory
390*61046927SAndroid Build Coastguard Worker */
391*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_bufferobj_data(struct gl_context * ctx,GLenum target,GLsizeiptrARB size,const void * data,GLenum usage,GLbitfield storageFlags,struct gl_buffer_object * obj)392*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_data(struct gl_context *ctx,
393*61046927SAndroid Build Coastguard Worker GLenum target,
394*61046927SAndroid Build Coastguard Worker GLsizeiptrARB size,
395*61046927SAndroid Build Coastguard Worker const void *data,
396*61046927SAndroid Build Coastguard Worker GLenum usage,
397*61046927SAndroid Build Coastguard Worker GLbitfield storageFlags,
398*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *obj)
399*61046927SAndroid Build Coastguard Worker {
400*61046927SAndroid Build Coastguard Worker return bufferobj_data(ctx, target, size, data, NULL, 0, usage, storageFlags, obj);
401*61046927SAndroid Build Coastguard Worker }
402*61046927SAndroid Build Coastguard Worker
403*61046927SAndroid Build Coastguard Worker static GLboolean
bufferobj_data_mem(struct gl_context * ctx,GLenum target,GLsizeiptrARB size,struct gl_memory_object * memObj,GLuint64 offset,GLenum usage,struct gl_buffer_object * bufObj)404*61046927SAndroid Build Coastguard Worker bufferobj_data_mem(struct gl_context *ctx,
405*61046927SAndroid Build Coastguard Worker GLenum target,
406*61046927SAndroid Build Coastguard Worker GLsizeiptrARB size,
407*61046927SAndroid Build Coastguard Worker struct gl_memory_object *memObj,
408*61046927SAndroid Build Coastguard Worker GLuint64 offset,
409*61046927SAndroid Build Coastguard Worker GLenum usage,
410*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj)
411*61046927SAndroid Build Coastguard Worker {
412*61046927SAndroid Build Coastguard Worker return bufferobj_data(ctx, target, size, NULL, memObj, offset, usage, GL_DYNAMIC_STORAGE_BIT, bufObj);
413*61046927SAndroid Build Coastguard Worker }
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker /**
416*61046927SAndroid Build Coastguard Worker * Convert GLbitfield of GL_MAP_x flags to gallium pipe_map_flags flags.
417*61046927SAndroid Build Coastguard Worker * \param wholeBuffer is the whole buffer being mapped?
418*61046927SAndroid Build Coastguard Worker */
419*61046927SAndroid Build Coastguard Worker enum pipe_map_flags
_mesa_access_flags_to_transfer_flags(GLbitfield access,bool wholeBuffer)420*61046927SAndroid Build Coastguard Worker _mesa_access_flags_to_transfer_flags(GLbitfield access, bool wholeBuffer)
421*61046927SAndroid Build Coastguard Worker {
422*61046927SAndroid Build Coastguard Worker enum pipe_map_flags flags = 0;
423*61046927SAndroid Build Coastguard Worker
424*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_WRITE_BIT)
425*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_WRITE;
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_READ_BIT)
428*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_READ;
429*61046927SAndroid Build Coastguard Worker
430*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_FLUSH_EXPLICIT_BIT)
431*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_FLUSH_EXPLICIT;
432*61046927SAndroid Build Coastguard Worker
433*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_INVALIDATE_BUFFER_BIT) {
434*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
435*61046927SAndroid Build Coastguard Worker }
436*61046927SAndroid Build Coastguard Worker else if (access & GL_MAP_INVALIDATE_RANGE_BIT) {
437*61046927SAndroid Build Coastguard Worker if (wholeBuffer)
438*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_DISCARD_WHOLE_RESOURCE;
439*61046927SAndroid Build Coastguard Worker else
440*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_DISCARD_RANGE;
441*61046927SAndroid Build Coastguard Worker }
442*61046927SAndroid Build Coastguard Worker
443*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_UNSYNCHRONIZED_BIT)
444*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_UNSYNCHRONIZED;
445*61046927SAndroid Build Coastguard Worker
446*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_PERSISTENT_BIT)
447*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_PERSISTENT;
448*61046927SAndroid Build Coastguard Worker
449*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_COHERENT_BIT)
450*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_COHERENT;
451*61046927SAndroid Build Coastguard Worker
452*61046927SAndroid Build Coastguard Worker /* ... other flags ...
453*61046927SAndroid Build Coastguard Worker */
454*61046927SAndroid Build Coastguard Worker
455*61046927SAndroid Build Coastguard Worker if (access & MESA_MAP_NOWAIT_BIT)
456*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_DONTBLOCK;
457*61046927SAndroid Build Coastguard Worker if (access & MESA_MAP_THREAD_SAFE_BIT)
458*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_THREAD_SAFE;
459*61046927SAndroid Build Coastguard Worker if (access & MESA_MAP_ONCE)
460*61046927SAndroid Build Coastguard Worker flags |= PIPE_MAP_ONCE;
461*61046927SAndroid Build Coastguard Worker
462*61046927SAndroid Build Coastguard Worker return flags;
463*61046927SAndroid Build Coastguard Worker }
464*61046927SAndroid Build Coastguard Worker
465*61046927SAndroid Build Coastguard Worker
466*61046927SAndroid Build Coastguard Worker /**
467*61046927SAndroid Build Coastguard Worker * Called via glMapBufferRange().
468*61046927SAndroid Build Coastguard Worker */
469*61046927SAndroid Build Coastguard Worker void *
_mesa_bufferobj_map_range(struct gl_context * ctx,GLintptr offset,GLsizeiptr length,GLbitfield access,struct gl_buffer_object * obj,gl_map_buffer_index index)470*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_map_range(struct gl_context *ctx,
471*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr length, GLbitfield access,
472*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *obj,
473*61046927SAndroid Build Coastguard Worker gl_map_buffer_index index)
474*61046927SAndroid Build Coastguard Worker {
475*61046927SAndroid Build Coastguard Worker struct pipe_context *pipe = ctx->pipe;
476*61046927SAndroid Build Coastguard Worker
477*61046927SAndroid Build Coastguard Worker assert(offset >= 0);
478*61046927SAndroid Build Coastguard Worker assert(length >= 0);
479*61046927SAndroid Build Coastguard Worker assert(offset < obj->Size);
480*61046927SAndroid Build Coastguard Worker assert(offset + length <= obj->Size);
481*61046927SAndroid Build Coastguard Worker
482*61046927SAndroid Build Coastguard Worker enum pipe_map_flags transfer_flags =
483*61046927SAndroid Build Coastguard Worker _mesa_access_flags_to_transfer_flags(access,
484*61046927SAndroid Build Coastguard Worker offset == 0 && length == obj->Size);
485*61046927SAndroid Build Coastguard Worker
486*61046927SAndroid Build Coastguard Worker /* Sometimes games do silly things like MapBufferRange(UNSYNC|DISCARD_RANGE)
487*61046927SAndroid Build Coastguard Worker * In this case, the the UNSYNC is a bit redundant, but the games rely
488*61046927SAndroid Build Coastguard Worker * on the driver rebinding/replacing the backing storage rather than
489*61046927SAndroid Build Coastguard Worker * going down the UNSYNC path (ie. honoring DISCARD_x first before UNSYNC).
490*61046927SAndroid Build Coastguard Worker */
491*61046927SAndroid Build Coastguard Worker if (unlikely(ctx->st_opts->ignore_map_unsynchronized)) {
492*61046927SAndroid Build Coastguard Worker if (transfer_flags & (PIPE_MAP_DISCARD_RANGE | PIPE_MAP_DISCARD_WHOLE_RESOURCE))
493*61046927SAndroid Build Coastguard Worker transfer_flags &= ~PIPE_MAP_UNSYNCHRONIZED;
494*61046927SAndroid Build Coastguard Worker }
495*61046927SAndroid Build Coastguard Worker
496*61046927SAndroid Build Coastguard Worker if (ctx->Const.ForceMapBufferSynchronized)
497*61046927SAndroid Build Coastguard Worker transfer_flags &= ~PIPE_MAP_UNSYNCHRONIZED;
498*61046927SAndroid Build Coastguard Worker
499*61046927SAndroid Build Coastguard Worker obj->Mappings[index].Pointer = pipe_buffer_map_range(pipe,
500*61046927SAndroid Build Coastguard Worker obj->buffer,
501*61046927SAndroid Build Coastguard Worker offset, length,
502*61046927SAndroid Build Coastguard Worker transfer_flags,
503*61046927SAndroid Build Coastguard Worker &obj->transfer[index]);
504*61046927SAndroid Build Coastguard Worker if (obj->Mappings[index].Pointer) {
505*61046927SAndroid Build Coastguard Worker obj->Mappings[index].Offset = offset;
506*61046927SAndroid Build Coastguard Worker obj->Mappings[index].Length = length;
507*61046927SAndroid Build Coastguard Worker obj->Mappings[index].AccessFlags = access;
508*61046927SAndroid Build Coastguard Worker }
509*61046927SAndroid Build Coastguard Worker else {
510*61046927SAndroid Build Coastguard Worker obj->transfer[index] = NULL;
511*61046927SAndroid Build Coastguard Worker }
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker return obj->Mappings[index].Pointer;
514*61046927SAndroid Build Coastguard Worker }
515*61046927SAndroid Build Coastguard Worker
516*61046927SAndroid Build Coastguard Worker
517*61046927SAndroid Build Coastguard Worker void
_mesa_bufferobj_flush_mapped_range(struct gl_context * ctx,GLintptr offset,GLsizeiptr length,struct gl_buffer_object * obj,gl_map_buffer_index index)518*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_flush_mapped_range(struct gl_context *ctx,
519*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr length,
520*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *obj,
521*61046927SAndroid Build Coastguard Worker gl_map_buffer_index index)
522*61046927SAndroid Build Coastguard Worker {
523*61046927SAndroid Build Coastguard Worker struct pipe_context *pipe = ctx->pipe;
524*61046927SAndroid Build Coastguard Worker
525*61046927SAndroid Build Coastguard Worker /* Subrange is relative to mapped range */
526*61046927SAndroid Build Coastguard Worker assert(offset >= 0);
527*61046927SAndroid Build Coastguard Worker assert(length >= 0);
528*61046927SAndroid Build Coastguard Worker assert(offset + length <= obj->Mappings[index].Length);
529*61046927SAndroid Build Coastguard Worker assert(obj->Mappings[index].Pointer);
530*61046927SAndroid Build Coastguard Worker
531*61046927SAndroid Build Coastguard Worker if (!length)
532*61046927SAndroid Build Coastguard Worker return;
533*61046927SAndroid Build Coastguard Worker
534*61046927SAndroid Build Coastguard Worker pipe_buffer_flush_mapped_range(pipe, obj->transfer[index],
535*61046927SAndroid Build Coastguard Worker obj->Mappings[index].Offset + offset,
536*61046927SAndroid Build Coastguard Worker length);
537*61046927SAndroid Build Coastguard Worker }
538*61046927SAndroid Build Coastguard Worker
539*61046927SAndroid Build Coastguard Worker
540*61046927SAndroid Build Coastguard Worker /**
541*61046927SAndroid Build Coastguard Worker * Called via glUnmapBufferARB().
542*61046927SAndroid Build Coastguard Worker */
543*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_bufferobj_unmap(struct gl_context * ctx,struct gl_buffer_object * obj,gl_map_buffer_index index)544*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj,
545*61046927SAndroid Build Coastguard Worker gl_map_buffer_index index)
546*61046927SAndroid Build Coastguard Worker {
547*61046927SAndroid Build Coastguard Worker struct pipe_context *pipe = ctx->pipe;
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker if (obj->Mappings[index].Length)
550*61046927SAndroid Build Coastguard Worker pipe_buffer_unmap(pipe, obj->transfer[index]);
551*61046927SAndroid Build Coastguard Worker
552*61046927SAndroid Build Coastguard Worker obj->transfer[index] = NULL;
553*61046927SAndroid Build Coastguard Worker obj->Mappings[index].Pointer = NULL;
554*61046927SAndroid Build Coastguard Worker obj->Mappings[index].Offset = 0;
555*61046927SAndroid Build Coastguard Worker obj->Mappings[index].Length = 0;
556*61046927SAndroid Build Coastguard Worker return GL_TRUE;
557*61046927SAndroid Build Coastguard Worker }
558*61046927SAndroid Build Coastguard Worker
559*61046927SAndroid Build Coastguard Worker
560*61046927SAndroid Build Coastguard Worker /**
561*61046927SAndroid Build Coastguard Worker * Called via glCopyBufferSubData().
562*61046927SAndroid Build Coastguard Worker */
563*61046927SAndroid Build Coastguard Worker static void
bufferobj_copy_subdata(struct gl_context * ctx,struct gl_buffer_object * src,struct gl_buffer_object * dst,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)564*61046927SAndroid Build Coastguard Worker bufferobj_copy_subdata(struct gl_context *ctx,
565*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *src,
566*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *dst,
567*61046927SAndroid Build Coastguard Worker GLintptr readOffset, GLintptr writeOffset,
568*61046927SAndroid Build Coastguard Worker GLsizeiptr size)
569*61046927SAndroid Build Coastguard Worker {
570*61046927SAndroid Build Coastguard Worker struct pipe_context *pipe = ctx->pipe;
571*61046927SAndroid Build Coastguard Worker struct pipe_box box;
572*61046927SAndroid Build Coastguard Worker
573*61046927SAndroid Build Coastguard Worker dst->MinMaxCacheDirty = true;
574*61046927SAndroid Build Coastguard Worker if (!size)
575*61046927SAndroid Build Coastguard Worker return;
576*61046927SAndroid Build Coastguard Worker
577*61046927SAndroid Build Coastguard Worker /* buffer should not already be mapped */
578*61046927SAndroid Build Coastguard Worker assert(!_mesa_check_disallowed_mapping(src));
579*61046927SAndroid Build Coastguard Worker /* dst can be mapped, just not the same range as the target range */
580*61046927SAndroid Build Coastguard Worker
581*61046927SAndroid Build Coastguard Worker u_box_1d(readOffset, size, &box);
582*61046927SAndroid Build Coastguard Worker
583*61046927SAndroid Build Coastguard Worker pipe->resource_copy_region(pipe, dst->buffer, 0, writeOffset, 0, 0,
584*61046927SAndroid Build Coastguard Worker src->buffer, 0, &box);
585*61046927SAndroid Build Coastguard Worker }
586*61046927SAndroid Build Coastguard Worker
587*61046927SAndroid Build Coastguard Worker static void
clear_buffer_subdata_sw(struct gl_context * ctx,GLintptr offset,GLsizeiptr size,const GLvoid * clearValue,GLsizeiptr clearValueSize,struct gl_buffer_object * bufObj)588*61046927SAndroid Build Coastguard Worker clear_buffer_subdata_sw(struct gl_context *ctx,
589*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size,
590*61046927SAndroid Build Coastguard Worker const GLvoid *clearValue,
591*61046927SAndroid Build Coastguard Worker GLsizeiptr clearValueSize,
592*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj)
593*61046927SAndroid Build Coastguard Worker {
594*61046927SAndroid Build Coastguard Worker GLsizeiptr i;
595*61046927SAndroid Build Coastguard Worker GLubyte *dest;
596*61046927SAndroid Build Coastguard Worker
597*61046927SAndroid Build Coastguard Worker dest = _mesa_bufferobj_map_range(ctx, offset, size,
598*61046927SAndroid Build Coastguard Worker GL_MAP_WRITE_BIT |
599*61046927SAndroid Build Coastguard Worker GL_MAP_INVALIDATE_RANGE_BIT,
600*61046927SAndroid Build Coastguard Worker bufObj, MAP_INTERNAL);
601*61046927SAndroid Build Coastguard Worker
602*61046927SAndroid Build Coastguard Worker if (!dest) {
603*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data");
604*61046927SAndroid Build Coastguard Worker return;
605*61046927SAndroid Build Coastguard Worker }
606*61046927SAndroid Build Coastguard Worker
607*61046927SAndroid Build Coastguard Worker if (clearValue == NULL) {
608*61046927SAndroid Build Coastguard Worker /* Clear with zeros, per the spec */
609*61046927SAndroid Build Coastguard Worker memset(dest, 0, size);
610*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_unmap(ctx, bufObj, MAP_INTERNAL);
611*61046927SAndroid Build Coastguard Worker return;
612*61046927SAndroid Build Coastguard Worker }
613*61046927SAndroid Build Coastguard Worker
614*61046927SAndroid Build Coastguard Worker for (i = 0; i < size/clearValueSize; ++i) {
615*61046927SAndroid Build Coastguard Worker memcpy(dest, clearValue, clearValueSize);
616*61046927SAndroid Build Coastguard Worker dest += clearValueSize;
617*61046927SAndroid Build Coastguard Worker }
618*61046927SAndroid Build Coastguard Worker
619*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_unmap(ctx, bufObj, MAP_INTERNAL);
620*61046927SAndroid Build Coastguard Worker }
621*61046927SAndroid Build Coastguard Worker
622*61046927SAndroid Build Coastguard Worker /**
623*61046927SAndroid Build Coastguard Worker * Helper to warn of possible performance issues, such as frequently
624*61046927SAndroid Build Coastguard Worker * updating a buffer created with GL_STATIC_DRAW. Called via the macro
625*61046927SAndroid Build Coastguard Worker * below.
626*61046927SAndroid Build Coastguard Worker */
627*61046927SAndroid Build Coastguard Worker static void
buffer_usage_warning(struct gl_context * ctx,GLuint * id,const char * fmt,...)628*61046927SAndroid Build Coastguard Worker buffer_usage_warning(struct gl_context *ctx, GLuint *id, const char *fmt, ...)
629*61046927SAndroid Build Coastguard Worker {
630*61046927SAndroid Build Coastguard Worker va_list args;
631*61046927SAndroid Build Coastguard Worker
632*61046927SAndroid Build Coastguard Worker va_start(args, fmt);
633*61046927SAndroid Build Coastguard Worker _mesa_gl_vdebugf(ctx, id,
634*61046927SAndroid Build Coastguard Worker MESA_DEBUG_SOURCE_API,
635*61046927SAndroid Build Coastguard Worker MESA_DEBUG_TYPE_PERFORMANCE,
636*61046927SAndroid Build Coastguard Worker MESA_DEBUG_SEVERITY_MEDIUM,
637*61046927SAndroid Build Coastguard Worker fmt, args);
638*61046927SAndroid Build Coastguard Worker va_end(args);
639*61046927SAndroid Build Coastguard Worker }
640*61046927SAndroid Build Coastguard Worker
641*61046927SAndroid Build Coastguard Worker #define BUFFER_USAGE_WARNING(CTX, FMT, ...) \
642*61046927SAndroid Build Coastguard Worker do { \
643*61046927SAndroid Build Coastguard Worker static GLuint id = 0; \
644*61046927SAndroid Build Coastguard Worker buffer_usage_warning(CTX, &id, FMT, ##__VA_ARGS__); \
645*61046927SAndroid Build Coastguard Worker } while (0)
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker
648*61046927SAndroid Build Coastguard Worker /**
649*61046927SAndroid Build Coastguard Worker * Used as a placeholder for buffer objects between glGenBuffers() and
650*61046927SAndroid Build Coastguard Worker * glBindBuffer() so that glIsBuffer() can work correctly.
651*61046927SAndroid Build Coastguard Worker */
652*61046927SAndroid Build Coastguard Worker static struct gl_buffer_object DummyBufferObject = {
653*61046927SAndroid Build Coastguard Worker .MinMaxCacheMutex = SIMPLE_MTX_INITIALIZER,
654*61046927SAndroid Build Coastguard Worker .RefCount = 1000*1000*1000, /* never delete */
655*61046927SAndroid Build Coastguard Worker };
656*61046927SAndroid Build Coastguard Worker
657*61046927SAndroid Build Coastguard Worker
658*61046927SAndroid Build Coastguard Worker /**
659*61046927SAndroid Build Coastguard Worker * Return pointer to address of a buffer object target.
660*61046927SAndroid Build Coastguard Worker * \param ctx the GL context
661*61046927SAndroid Build Coastguard Worker * \param target the buffer object target to be retrieved.
662*61046927SAndroid Build Coastguard Worker * \return pointer to pointer to the buffer object bound to \c target in the
663*61046927SAndroid Build Coastguard Worker * specified context or \c NULL if \c target is invalid.
664*61046927SAndroid Build Coastguard Worker */
665*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE struct gl_buffer_object **
get_buffer_target(struct gl_context * ctx,GLenum target,bool no_error)666*61046927SAndroid Build Coastguard Worker get_buffer_target(struct gl_context *ctx, GLenum target, bool no_error)
667*61046927SAndroid Build Coastguard Worker {
668*61046927SAndroid Build Coastguard Worker /* Other targets are only supported in desktop OpenGL and OpenGL ES 3.0. */
669*61046927SAndroid Build Coastguard Worker if (!no_error && !_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) {
670*61046927SAndroid Build Coastguard Worker switch (target) {
671*61046927SAndroid Build Coastguard Worker case GL_ARRAY_BUFFER:
672*61046927SAndroid Build Coastguard Worker case GL_ELEMENT_ARRAY_BUFFER:
673*61046927SAndroid Build Coastguard Worker case GL_PIXEL_PACK_BUFFER:
674*61046927SAndroid Build Coastguard Worker case GL_PIXEL_UNPACK_BUFFER:
675*61046927SAndroid Build Coastguard Worker break;
676*61046927SAndroid Build Coastguard Worker default:
677*61046927SAndroid Build Coastguard Worker return NULL;
678*61046927SAndroid Build Coastguard Worker }
679*61046927SAndroid Build Coastguard Worker }
680*61046927SAndroid Build Coastguard Worker
681*61046927SAndroid Build Coastguard Worker switch (target) {
682*61046927SAndroid Build Coastguard Worker case GL_ARRAY_BUFFER_ARB:
683*61046927SAndroid Build Coastguard Worker return &ctx->Array.ArrayBufferObj;
684*61046927SAndroid Build Coastguard Worker case GL_ELEMENT_ARRAY_BUFFER_ARB:
685*61046927SAndroid Build Coastguard Worker return &ctx->Array.VAO->IndexBufferObj;
686*61046927SAndroid Build Coastguard Worker case GL_PIXEL_PACK_BUFFER_EXT:
687*61046927SAndroid Build Coastguard Worker return &ctx->Pack.BufferObj;
688*61046927SAndroid Build Coastguard Worker case GL_PIXEL_UNPACK_BUFFER_EXT:
689*61046927SAndroid Build Coastguard Worker return &ctx->Unpack.BufferObj;
690*61046927SAndroid Build Coastguard Worker case GL_COPY_READ_BUFFER:
691*61046927SAndroid Build Coastguard Worker return &ctx->CopyReadBuffer;
692*61046927SAndroid Build Coastguard Worker case GL_COPY_WRITE_BUFFER:
693*61046927SAndroid Build Coastguard Worker return &ctx->CopyWriteBuffer;
694*61046927SAndroid Build Coastguard Worker case GL_QUERY_BUFFER:
695*61046927SAndroid Build Coastguard Worker if (no_error || _mesa_has_ARB_query_buffer_object(ctx))
696*61046927SAndroid Build Coastguard Worker return &ctx->QueryBuffer;
697*61046927SAndroid Build Coastguard Worker break;
698*61046927SAndroid Build Coastguard Worker case GL_DRAW_INDIRECT_BUFFER:
699*61046927SAndroid Build Coastguard Worker if (no_error ||
700*61046927SAndroid Build Coastguard Worker (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_draw_indirect) ||
701*61046927SAndroid Build Coastguard Worker _mesa_is_gles31(ctx)) {
702*61046927SAndroid Build Coastguard Worker return &ctx->DrawIndirectBuffer;
703*61046927SAndroid Build Coastguard Worker }
704*61046927SAndroid Build Coastguard Worker break;
705*61046927SAndroid Build Coastguard Worker case GL_PARAMETER_BUFFER_ARB:
706*61046927SAndroid Build Coastguard Worker if (no_error || _mesa_has_ARB_indirect_parameters(ctx)) {
707*61046927SAndroid Build Coastguard Worker return &ctx->ParameterBuffer;
708*61046927SAndroid Build Coastguard Worker }
709*61046927SAndroid Build Coastguard Worker break;
710*61046927SAndroid Build Coastguard Worker case GL_DISPATCH_INDIRECT_BUFFER:
711*61046927SAndroid Build Coastguard Worker if (no_error || _mesa_has_compute_shaders(ctx)) {
712*61046927SAndroid Build Coastguard Worker return &ctx->DispatchIndirectBuffer;
713*61046927SAndroid Build Coastguard Worker }
714*61046927SAndroid Build Coastguard Worker break;
715*61046927SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_BUFFER:
716*61046927SAndroid Build Coastguard Worker if (no_error || ctx->Extensions.EXT_transform_feedback) {
717*61046927SAndroid Build Coastguard Worker return &ctx->TransformFeedback.CurrentBuffer;
718*61046927SAndroid Build Coastguard Worker }
719*61046927SAndroid Build Coastguard Worker break;
720*61046927SAndroid Build Coastguard Worker case GL_TEXTURE_BUFFER:
721*61046927SAndroid Build Coastguard Worker if (no_error ||
722*61046927SAndroid Build Coastguard Worker _mesa_has_ARB_texture_buffer_object(ctx) ||
723*61046927SAndroid Build Coastguard Worker _mesa_has_OES_texture_buffer(ctx)) {
724*61046927SAndroid Build Coastguard Worker return &ctx->Texture.BufferObject;
725*61046927SAndroid Build Coastguard Worker }
726*61046927SAndroid Build Coastguard Worker break;
727*61046927SAndroid Build Coastguard Worker case GL_UNIFORM_BUFFER:
728*61046927SAndroid Build Coastguard Worker if (no_error || ctx->Extensions.ARB_uniform_buffer_object) {
729*61046927SAndroid Build Coastguard Worker return &ctx->UniformBuffer;
730*61046927SAndroid Build Coastguard Worker }
731*61046927SAndroid Build Coastguard Worker break;
732*61046927SAndroid Build Coastguard Worker case GL_SHADER_STORAGE_BUFFER:
733*61046927SAndroid Build Coastguard Worker if (no_error ||
734*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_shader_storage_buffer_object ||
735*61046927SAndroid Build Coastguard Worker _mesa_is_gles31(ctx)) {
736*61046927SAndroid Build Coastguard Worker return &ctx->ShaderStorageBuffer;
737*61046927SAndroid Build Coastguard Worker }
738*61046927SAndroid Build Coastguard Worker break;
739*61046927SAndroid Build Coastguard Worker case GL_ATOMIC_COUNTER_BUFFER:
740*61046927SAndroid Build Coastguard Worker if (no_error ||
741*61046927SAndroid Build Coastguard Worker ctx->Extensions.ARB_shader_atomic_counters || _mesa_is_gles31(ctx)) {
742*61046927SAndroid Build Coastguard Worker return &ctx->AtomicBuffer;
743*61046927SAndroid Build Coastguard Worker }
744*61046927SAndroid Build Coastguard Worker break;
745*61046927SAndroid Build Coastguard Worker case GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD:
746*61046927SAndroid Build Coastguard Worker if (no_error || ctx->Extensions.AMD_pinned_memory) {
747*61046927SAndroid Build Coastguard Worker return &ctx->ExternalVirtualMemoryBuffer;
748*61046927SAndroid Build Coastguard Worker }
749*61046927SAndroid Build Coastguard Worker break;
750*61046927SAndroid Build Coastguard Worker }
751*61046927SAndroid Build Coastguard Worker return NULL;
752*61046927SAndroid Build Coastguard Worker }
753*61046927SAndroid Build Coastguard Worker
754*61046927SAndroid Build Coastguard Worker
755*61046927SAndroid Build Coastguard Worker /**
756*61046927SAndroid Build Coastguard Worker * Get the buffer object bound to the specified target in a GL context.
757*61046927SAndroid Build Coastguard Worker * \param ctx the GL context
758*61046927SAndroid Build Coastguard Worker * \param target the buffer object target to be retrieved.
759*61046927SAndroid Build Coastguard Worker * \param error the GL error to record if target is illegal.
760*61046927SAndroid Build Coastguard Worker * \return pointer to the buffer object bound to \c target in the
761*61046927SAndroid Build Coastguard Worker * specified context or \c NULL if \c target is invalid.
762*61046927SAndroid Build Coastguard Worker */
763*61046927SAndroid Build Coastguard Worker static inline struct gl_buffer_object *
get_buffer(struct gl_context * ctx,const char * func,GLenum target,GLenum error)764*61046927SAndroid Build Coastguard Worker get_buffer(struct gl_context *ctx, const char *func, GLenum target,
765*61046927SAndroid Build Coastguard Worker GLenum error)
766*61046927SAndroid Build Coastguard Worker {
767*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObj = get_buffer_target(ctx, target, false);
768*61046927SAndroid Build Coastguard Worker
769*61046927SAndroid Build Coastguard Worker if (!bufObj) {
770*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func);
771*61046927SAndroid Build Coastguard Worker return NULL;
772*61046927SAndroid Build Coastguard Worker }
773*61046927SAndroid Build Coastguard Worker
774*61046927SAndroid Build Coastguard Worker if (!*bufObj) {
775*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, error, "%s(no buffer bound)", func);
776*61046927SAndroid Build Coastguard Worker return NULL;
777*61046927SAndroid Build Coastguard Worker }
778*61046927SAndroid Build Coastguard Worker
779*61046927SAndroid Build Coastguard Worker return *bufObj;
780*61046927SAndroid Build Coastguard Worker }
781*61046927SAndroid Build Coastguard Worker
782*61046927SAndroid Build Coastguard Worker
783*61046927SAndroid Build Coastguard Worker /**
784*61046927SAndroid Build Coastguard Worker * Convert a GLbitfield describing the mapped buffer access flags
785*61046927SAndroid Build Coastguard Worker * into one of GL_READ_WRITE, GL_READ_ONLY, or GL_WRITE_ONLY.
786*61046927SAndroid Build Coastguard Worker */
787*61046927SAndroid Build Coastguard Worker static GLenum
simplified_access_mode(struct gl_context * ctx,GLbitfield access)788*61046927SAndroid Build Coastguard Worker simplified_access_mode(struct gl_context *ctx, GLbitfield access)
789*61046927SAndroid Build Coastguard Worker {
790*61046927SAndroid Build Coastguard Worker const GLbitfield rwFlags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
791*61046927SAndroid Build Coastguard Worker if ((access & rwFlags) == rwFlags)
792*61046927SAndroid Build Coastguard Worker return GL_READ_WRITE;
793*61046927SAndroid Build Coastguard Worker if ((access & GL_MAP_READ_BIT) == GL_MAP_READ_BIT)
794*61046927SAndroid Build Coastguard Worker return GL_READ_ONLY;
795*61046927SAndroid Build Coastguard Worker if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT)
796*61046927SAndroid Build Coastguard Worker return GL_WRITE_ONLY;
797*61046927SAndroid Build Coastguard Worker
798*61046927SAndroid Build Coastguard Worker /* Otherwise, AccessFlags is zero (the default state).
799*61046927SAndroid Build Coastguard Worker *
800*61046927SAndroid Build Coastguard Worker * Table 2.6 on page 31 (page 44 of the PDF) of the OpenGL 1.5 spec says:
801*61046927SAndroid Build Coastguard Worker *
802*61046927SAndroid Build Coastguard Worker * Name Type Initial Value Legal Values
803*61046927SAndroid Build Coastguard Worker * ... ... ... ...
804*61046927SAndroid Build Coastguard Worker * BUFFER_ACCESS enum READ_WRITE READ_ONLY, WRITE_ONLY
805*61046927SAndroid Build Coastguard Worker * READ_WRITE
806*61046927SAndroid Build Coastguard Worker *
807*61046927SAndroid Build Coastguard Worker * However, table 6.8 in the GL_OES_mapbuffer extension says:
808*61046927SAndroid Build Coastguard Worker *
809*61046927SAndroid Build Coastguard Worker * Get Value Type Get Command Value Description
810*61046927SAndroid Build Coastguard Worker * --------- ---- ----------- ----- -----------
811*61046927SAndroid Build Coastguard Worker * BUFFER_ACCESS_OES Z1 GetBufferParameteriv WRITE_ONLY_OES buffer map flag
812*61046927SAndroid Build Coastguard Worker *
813*61046927SAndroid Build Coastguard Worker * The difference is because GL_OES_mapbuffer only supports mapping buffers
814*61046927SAndroid Build Coastguard Worker * write-only.
815*61046927SAndroid Build Coastguard Worker */
816*61046927SAndroid Build Coastguard Worker assert(access == 0);
817*61046927SAndroid Build Coastguard Worker
818*61046927SAndroid Build Coastguard Worker return _mesa_is_gles(ctx) ? GL_WRITE_ONLY : GL_READ_WRITE;
819*61046927SAndroid Build Coastguard Worker }
820*61046927SAndroid Build Coastguard Worker
821*61046927SAndroid Build Coastguard Worker
822*61046927SAndroid Build Coastguard Worker /**
823*61046927SAndroid Build Coastguard Worker * Test if the buffer is mapped, and if so, if the mapped range overlaps the
824*61046927SAndroid Build Coastguard Worker * given range.
825*61046927SAndroid Build Coastguard Worker * The regions do not overlap if and only if the end of the given
826*61046927SAndroid Build Coastguard Worker * region is before the mapped region or the start of the given region
827*61046927SAndroid Build Coastguard Worker * is after the mapped region.
828*61046927SAndroid Build Coastguard Worker *
829*61046927SAndroid Build Coastguard Worker * \param obj Buffer object target on which to operate.
830*61046927SAndroid Build Coastguard Worker * \param offset Offset of the first byte of the subdata range.
831*61046927SAndroid Build Coastguard Worker * \param size Size, in bytes, of the subdata range.
832*61046927SAndroid Build Coastguard Worker * \return true if ranges overlap, false otherwise
833*61046927SAndroid Build Coastguard Worker *
834*61046927SAndroid Build Coastguard Worker */
835*61046927SAndroid Build Coastguard Worker static bool
bufferobj_range_mapped(const struct gl_buffer_object * obj,GLintptr offset,GLsizeiptr size)836*61046927SAndroid Build Coastguard Worker bufferobj_range_mapped(const struct gl_buffer_object *obj,
837*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size)
838*61046927SAndroid Build Coastguard Worker {
839*61046927SAndroid Build Coastguard Worker if (_mesa_bufferobj_mapped(obj, MAP_USER)) {
840*61046927SAndroid Build Coastguard Worker const GLintptr end = offset + size;
841*61046927SAndroid Build Coastguard Worker const GLintptr mapEnd = obj->Mappings[MAP_USER].Offset +
842*61046927SAndroid Build Coastguard Worker obj->Mappings[MAP_USER].Length;
843*61046927SAndroid Build Coastguard Worker
844*61046927SAndroid Build Coastguard Worker if (!(end <= obj->Mappings[MAP_USER].Offset || offset >= mapEnd)) {
845*61046927SAndroid Build Coastguard Worker return true;
846*61046927SAndroid Build Coastguard Worker }
847*61046927SAndroid Build Coastguard Worker }
848*61046927SAndroid Build Coastguard Worker return false;
849*61046927SAndroid Build Coastguard Worker }
850*61046927SAndroid Build Coastguard Worker
851*61046927SAndroid Build Coastguard Worker
852*61046927SAndroid Build Coastguard Worker /**
853*61046927SAndroid Build Coastguard Worker * Tests the subdata range parameters and sets the GL error code for
854*61046927SAndroid Build Coastguard Worker * \c glBufferSubDataARB, \c glGetBufferSubDataARB and
855*61046927SAndroid Build Coastguard Worker * \c glClearBufferSubData.
856*61046927SAndroid Build Coastguard Worker *
857*61046927SAndroid Build Coastguard Worker * \param ctx GL context.
858*61046927SAndroid Build Coastguard Worker * \param bufObj The buffer object.
859*61046927SAndroid Build Coastguard Worker * \param offset Offset of the first byte of the subdata range.
860*61046927SAndroid Build Coastguard Worker * \param size Size, in bytes, of the subdata range.
861*61046927SAndroid Build Coastguard Worker * \param mappedRange If true, checks if an overlapping range is mapped.
862*61046927SAndroid Build Coastguard Worker * If false, checks if buffer is mapped.
863*61046927SAndroid Build Coastguard Worker * \param caller Name of calling function for recording errors.
864*61046927SAndroid Build Coastguard Worker * \return false if error, true otherwise
865*61046927SAndroid Build Coastguard Worker *
866*61046927SAndroid Build Coastguard Worker * \sa glBufferSubDataARB, glGetBufferSubDataARB, glClearBufferSubData
867*61046927SAndroid Build Coastguard Worker */
868*61046927SAndroid Build Coastguard Worker static bool
buffer_object_subdata_range_good(struct gl_context * ctx,const struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,bool mappedRange,const char * caller)869*61046927SAndroid Build Coastguard Worker buffer_object_subdata_range_good(struct gl_context *ctx,
870*61046927SAndroid Build Coastguard Worker const struct gl_buffer_object *bufObj,
871*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size,
872*61046927SAndroid Build Coastguard Worker bool mappedRange, const char *caller)
873*61046927SAndroid Build Coastguard Worker {
874*61046927SAndroid Build Coastguard Worker if (size < 0) {
875*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(size < 0)", caller);
876*61046927SAndroid Build Coastguard Worker return false;
877*61046927SAndroid Build Coastguard Worker }
878*61046927SAndroid Build Coastguard Worker
879*61046927SAndroid Build Coastguard Worker if (offset < 0) {
880*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset < 0)", caller);
881*61046927SAndroid Build Coastguard Worker return false;
882*61046927SAndroid Build Coastguard Worker }
883*61046927SAndroid Build Coastguard Worker
884*61046927SAndroid Build Coastguard Worker if (offset + size > bufObj->Size) {
885*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
886*61046927SAndroid Build Coastguard Worker "%s(offset %lu + size %lu > buffer size %lu)", caller,
887*61046927SAndroid Build Coastguard Worker (unsigned long) offset,
888*61046927SAndroid Build Coastguard Worker (unsigned long) size,
889*61046927SAndroid Build Coastguard Worker (unsigned long) bufObj->Size);
890*61046927SAndroid Build Coastguard Worker return false;
891*61046927SAndroid Build Coastguard Worker }
892*61046927SAndroid Build Coastguard Worker
893*61046927SAndroid Build Coastguard Worker if (bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_PERSISTENT_BIT)
894*61046927SAndroid Build Coastguard Worker return true;
895*61046927SAndroid Build Coastguard Worker
896*61046927SAndroid Build Coastguard Worker if (mappedRange) {
897*61046927SAndroid Build Coastguard Worker if (bufferobj_range_mapped(bufObj, offset, size)) {
898*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
899*61046927SAndroid Build Coastguard Worker "%s(range is mapped without persistent bit)",
900*61046927SAndroid Build Coastguard Worker caller);
901*61046927SAndroid Build Coastguard Worker return false;
902*61046927SAndroid Build Coastguard Worker }
903*61046927SAndroid Build Coastguard Worker }
904*61046927SAndroid Build Coastguard Worker else {
905*61046927SAndroid Build Coastguard Worker if (_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
906*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
907*61046927SAndroid Build Coastguard Worker "%s(buffer is mapped without persistent bit)",
908*61046927SAndroid Build Coastguard Worker caller);
909*61046927SAndroid Build Coastguard Worker return false;
910*61046927SAndroid Build Coastguard Worker }
911*61046927SAndroid Build Coastguard Worker }
912*61046927SAndroid Build Coastguard Worker
913*61046927SAndroid Build Coastguard Worker return true;
914*61046927SAndroid Build Coastguard Worker }
915*61046927SAndroid Build Coastguard Worker
916*61046927SAndroid Build Coastguard Worker
917*61046927SAndroid Build Coastguard Worker /**
918*61046927SAndroid Build Coastguard Worker * Test the format and type parameters and set the GL error code for
919*61046927SAndroid Build Coastguard Worker * \c glClearBufferData, \c glClearNamedBufferData, \c glClearBufferSubData
920*61046927SAndroid Build Coastguard Worker * and \c glClearNamedBufferSubData.
921*61046927SAndroid Build Coastguard Worker *
922*61046927SAndroid Build Coastguard Worker * \param ctx GL context.
923*61046927SAndroid Build Coastguard Worker * \param internalformat Format to which the data is to be converted.
924*61046927SAndroid Build Coastguard Worker * \param format Format of the supplied data.
925*61046927SAndroid Build Coastguard Worker * \param type Type of the supplied data.
926*61046927SAndroid Build Coastguard Worker * \param caller Name of calling function for recording errors.
927*61046927SAndroid Build Coastguard Worker * \return If internalformat, format and type are legal the mesa_format
928*61046927SAndroid Build Coastguard Worker * corresponding to internalformat, otherwise MESA_FORMAT_NONE.
929*61046927SAndroid Build Coastguard Worker *
930*61046927SAndroid Build Coastguard Worker * \sa glClearBufferData, glClearNamedBufferData, glClearBufferSubData and
931*61046927SAndroid Build Coastguard Worker * glClearNamedBufferSubData.
932*61046927SAndroid Build Coastguard Worker */
933*61046927SAndroid Build Coastguard Worker static mesa_format
validate_clear_buffer_format(struct gl_context * ctx,GLenum internalformat,GLenum format,GLenum type,const char * caller)934*61046927SAndroid Build Coastguard Worker validate_clear_buffer_format(struct gl_context *ctx,
935*61046927SAndroid Build Coastguard Worker GLenum internalformat,
936*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type,
937*61046927SAndroid Build Coastguard Worker const char *caller)
938*61046927SAndroid Build Coastguard Worker {
939*61046927SAndroid Build Coastguard Worker mesa_format mesaFormat;
940*61046927SAndroid Build Coastguard Worker GLenum errorFormatType;
941*61046927SAndroid Build Coastguard Worker
942*61046927SAndroid Build Coastguard Worker mesaFormat = _mesa_validate_texbuffer_format(ctx, internalformat);
943*61046927SAndroid Build Coastguard Worker if (mesaFormat == MESA_FORMAT_NONE) {
944*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
945*61046927SAndroid Build Coastguard Worker "%s(invalid internalformat)", caller);
946*61046927SAndroid Build Coastguard Worker return MESA_FORMAT_NONE;
947*61046927SAndroid Build Coastguard Worker }
948*61046927SAndroid Build Coastguard Worker
949*61046927SAndroid Build Coastguard Worker /* NOTE: not mentioned in ARB_clear_buffer_object but according to
950*61046927SAndroid Build Coastguard Worker * EXT_texture_integer there is no conversion between integer and
951*61046927SAndroid Build Coastguard Worker * non-integer formats
952*61046927SAndroid Build Coastguard Worker */
953*61046927SAndroid Build Coastguard Worker if (_mesa_is_enum_format_signed_int(format) !=
954*61046927SAndroid Build Coastguard Worker _mesa_is_format_integer_color(mesaFormat)) {
955*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
956*61046927SAndroid Build Coastguard Worker "%s(integer vs non-integer)", caller);
957*61046927SAndroid Build Coastguard Worker return MESA_FORMAT_NONE;
958*61046927SAndroid Build Coastguard Worker }
959*61046927SAndroid Build Coastguard Worker
960*61046927SAndroid Build Coastguard Worker if (!_mesa_is_color_format(format)) {
961*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
962*61046927SAndroid Build Coastguard Worker "%s(format is not a color format)", caller);
963*61046927SAndroid Build Coastguard Worker return MESA_FORMAT_NONE;
964*61046927SAndroid Build Coastguard Worker }
965*61046927SAndroid Build Coastguard Worker
966*61046927SAndroid Build Coastguard Worker errorFormatType = _mesa_error_check_format_and_type(ctx, format, type);
967*61046927SAndroid Build Coastguard Worker if (errorFormatType != GL_NO_ERROR) {
968*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
969*61046927SAndroid Build Coastguard Worker "%s(invalid format or type)", caller);
970*61046927SAndroid Build Coastguard Worker return MESA_FORMAT_NONE;
971*61046927SAndroid Build Coastguard Worker }
972*61046927SAndroid Build Coastguard Worker
973*61046927SAndroid Build Coastguard Worker return mesaFormat;
974*61046927SAndroid Build Coastguard Worker }
975*61046927SAndroid Build Coastguard Worker
976*61046927SAndroid Build Coastguard Worker
977*61046927SAndroid Build Coastguard Worker /**
978*61046927SAndroid Build Coastguard Worker * Convert user-specified clear value to the specified internal format.
979*61046927SAndroid Build Coastguard Worker *
980*61046927SAndroid Build Coastguard Worker * \param ctx GL context.
981*61046927SAndroid Build Coastguard Worker * \param internalformat Format to which the data is converted.
982*61046927SAndroid Build Coastguard Worker * \param clearValue Points to the converted clear value.
983*61046927SAndroid Build Coastguard Worker * \param format Format of the supplied data.
984*61046927SAndroid Build Coastguard Worker * \param type Type of the supplied data.
985*61046927SAndroid Build Coastguard Worker * \param data Data which is to be converted to internalformat.
986*61046927SAndroid Build Coastguard Worker * \param caller Name of calling function for recording errors.
987*61046927SAndroid Build Coastguard Worker * \return true if data could be converted, false otherwise.
988*61046927SAndroid Build Coastguard Worker *
989*61046927SAndroid Build Coastguard Worker * \sa glClearBufferData, glClearBufferSubData
990*61046927SAndroid Build Coastguard Worker */
991*61046927SAndroid Build Coastguard Worker static bool
convert_clear_buffer_data(struct gl_context * ctx,mesa_format internalformat,GLubyte * clearValue,GLenum format,GLenum type,const GLvoid * data,const char * caller)992*61046927SAndroid Build Coastguard Worker convert_clear_buffer_data(struct gl_context *ctx,
993*61046927SAndroid Build Coastguard Worker mesa_format internalformat,
994*61046927SAndroid Build Coastguard Worker GLubyte *clearValue, GLenum format, GLenum type,
995*61046927SAndroid Build Coastguard Worker const GLvoid *data, const char *caller)
996*61046927SAndroid Build Coastguard Worker {
997*61046927SAndroid Build Coastguard Worker GLenum internalformatBase = _mesa_get_format_base_format(internalformat);
998*61046927SAndroid Build Coastguard Worker
999*61046927SAndroid Build Coastguard Worker if (_mesa_texstore(ctx, 1, internalformatBase, internalformat,
1000*61046927SAndroid Build Coastguard Worker 0, &clearValue, 1, 1, 1,
1001*61046927SAndroid Build Coastguard Worker format, type, data, &ctx->Unpack)) {
1002*61046927SAndroid Build Coastguard Worker return true;
1003*61046927SAndroid Build Coastguard Worker }
1004*61046927SAndroid Build Coastguard Worker else {
1005*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
1006*61046927SAndroid Build Coastguard Worker return false;
1007*61046927SAndroid Build Coastguard Worker }
1008*61046927SAndroid Build Coastguard Worker }
1009*61046927SAndroid Build Coastguard Worker
1010*61046927SAndroid Build Coastguard Worker void
_mesa_bufferobj_release_buffer(struct gl_buffer_object * obj)1011*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_release_buffer(struct gl_buffer_object *obj)
1012*61046927SAndroid Build Coastguard Worker {
1013*61046927SAndroid Build Coastguard Worker if (!obj->buffer)
1014*61046927SAndroid Build Coastguard Worker return;
1015*61046927SAndroid Build Coastguard Worker
1016*61046927SAndroid Build Coastguard Worker /* Subtract the remaining private references before unreferencing
1017*61046927SAndroid Build Coastguard Worker * the buffer. See the header file for explanation.
1018*61046927SAndroid Build Coastguard Worker */
1019*61046927SAndroid Build Coastguard Worker if (obj->private_refcount) {
1020*61046927SAndroid Build Coastguard Worker assert(obj->private_refcount > 0);
1021*61046927SAndroid Build Coastguard Worker p_atomic_add(&obj->buffer->reference.count,
1022*61046927SAndroid Build Coastguard Worker -obj->private_refcount);
1023*61046927SAndroid Build Coastguard Worker obj->private_refcount = 0;
1024*61046927SAndroid Build Coastguard Worker }
1025*61046927SAndroid Build Coastguard Worker obj->private_refcount_ctx = NULL;
1026*61046927SAndroid Build Coastguard Worker
1027*61046927SAndroid Build Coastguard Worker pipe_resource_reference(&obj->buffer, NULL);
1028*61046927SAndroid Build Coastguard Worker }
1029*61046927SAndroid Build Coastguard Worker
1030*61046927SAndroid Build Coastguard Worker /**
1031*61046927SAndroid Build Coastguard Worker * Delete a buffer object.
1032*61046927SAndroid Build Coastguard Worker *
1033*61046927SAndroid Build Coastguard Worker * Default callback for the \c dd_function_table::DeleteBuffer() hook.
1034*61046927SAndroid Build Coastguard Worker */
1035*61046927SAndroid Build Coastguard Worker void
_mesa_delete_buffer_object(struct gl_context * ctx,struct gl_buffer_object * bufObj)1036*61046927SAndroid Build Coastguard Worker _mesa_delete_buffer_object(struct gl_context *ctx,
1037*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj)
1038*61046927SAndroid Build Coastguard Worker {
1039*61046927SAndroid Build Coastguard Worker assert(bufObj->RefCount == 0);
1040*61046927SAndroid Build Coastguard Worker _mesa_buffer_unmap_all_mappings(ctx, bufObj);
1041*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_release_buffer(bufObj);
1042*61046927SAndroid Build Coastguard Worker
1043*61046927SAndroid Build Coastguard Worker vbo_delete_minmax_cache(bufObj);
1044*61046927SAndroid Build Coastguard Worker
1045*61046927SAndroid Build Coastguard Worker /* assign strange values here to help w/ debugging */
1046*61046927SAndroid Build Coastguard Worker bufObj->RefCount = -1000;
1047*61046927SAndroid Build Coastguard Worker bufObj->Name = ~0;
1048*61046927SAndroid Build Coastguard Worker
1049*61046927SAndroid Build Coastguard Worker simple_mtx_destroy(&bufObj->MinMaxCacheMutex);
1050*61046927SAndroid Build Coastguard Worker free(bufObj->Label);
1051*61046927SAndroid Build Coastguard Worker free(bufObj);
1052*61046927SAndroid Build Coastguard Worker }
1053*61046927SAndroid Build Coastguard Worker
1054*61046927SAndroid Build Coastguard Worker
1055*61046927SAndroid Build Coastguard Worker /**
1056*61046927SAndroid Build Coastguard Worker * Get the value of MESA_NO_MINMAX_CACHE.
1057*61046927SAndroid Build Coastguard Worker */
1058*61046927SAndroid Build Coastguard Worker static bool
get_no_minmax_cache()1059*61046927SAndroid Build Coastguard Worker get_no_minmax_cache()
1060*61046927SAndroid Build Coastguard Worker {
1061*61046927SAndroid Build Coastguard Worker static bool read = false;
1062*61046927SAndroid Build Coastguard Worker static bool disable = false;
1063*61046927SAndroid Build Coastguard Worker
1064*61046927SAndroid Build Coastguard Worker if (!read) {
1065*61046927SAndroid Build Coastguard Worker disable = debug_get_bool_option("MESA_NO_MINMAX_CACHE", false);
1066*61046927SAndroid Build Coastguard Worker read = true;
1067*61046927SAndroid Build Coastguard Worker }
1068*61046927SAndroid Build Coastguard Worker
1069*61046927SAndroid Build Coastguard Worker return disable;
1070*61046927SAndroid Build Coastguard Worker }
1071*61046927SAndroid Build Coastguard Worker
1072*61046927SAndroid Build Coastguard Worker /**
1073*61046927SAndroid Build Coastguard Worker * Callback called from _mesa_HashWalk()
1074*61046927SAndroid Build Coastguard Worker */
1075*61046927SAndroid Build Coastguard Worker static void
count_buffer_size(void * data,void * userData)1076*61046927SAndroid Build Coastguard Worker count_buffer_size(void *data, void *userData)
1077*61046927SAndroid Build Coastguard Worker {
1078*61046927SAndroid Build Coastguard Worker const struct gl_buffer_object *bufObj =
1079*61046927SAndroid Build Coastguard Worker (const struct gl_buffer_object *) data;
1080*61046927SAndroid Build Coastguard Worker GLuint *total = (GLuint *) userData;
1081*61046927SAndroid Build Coastguard Worker
1082*61046927SAndroid Build Coastguard Worker *total = *total + bufObj->Size;
1083*61046927SAndroid Build Coastguard Worker }
1084*61046927SAndroid Build Coastguard Worker
1085*61046927SAndroid Build Coastguard Worker
1086*61046927SAndroid Build Coastguard Worker /**
1087*61046927SAndroid Build Coastguard Worker * Initialize the state associated with buffer objects
1088*61046927SAndroid Build Coastguard Worker */
1089*61046927SAndroid Build Coastguard Worker void
_mesa_init_buffer_objects(struct gl_context * ctx)1090*61046927SAndroid Build Coastguard Worker _mesa_init_buffer_objects( struct gl_context *ctx )
1091*61046927SAndroid Build Coastguard Worker {
1092*61046927SAndroid Build Coastguard Worker GLuint i;
1093*61046927SAndroid Build Coastguard Worker
1094*61046927SAndroid Build Coastguard Worker for (i = 0; i < MAX_COMBINED_UNIFORM_BUFFERS; i++) {
1095*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx,
1096*61046927SAndroid Build Coastguard Worker &ctx->UniformBufferBindings[i].BufferObject,
1097*61046927SAndroid Build Coastguard Worker NULL);
1098*61046927SAndroid Build Coastguard Worker ctx->UniformBufferBindings[i].Offset = -1;
1099*61046927SAndroid Build Coastguard Worker ctx->UniformBufferBindings[i].Size = -1;
1100*61046927SAndroid Build Coastguard Worker }
1101*61046927SAndroid Build Coastguard Worker
1102*61046927SAndroid Build Coastguard Worker for (i = 0; i < MAX_COMBINED_SHADER_STORAGE_BUFFERS; i++) {
1103*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx,
1104*61046927SAndroid Build Coastguard Worker &ctx->ShaderStorageBufferBindings[i].BufferObject,
1105*61046927SAndroid Build Coastguard Worker NULL);
1106*61046927SAndroid Build Coastguard Worker ctx->ShaderStorageBufferBindings[i].Offset = -1;
1107*61046927SAndroid Build Coastguard Worker ctx->ShaderStorageBufferBindings[i].Size = -1;
1108*61046927SAndroid Build Coastguard Worker }
1109*61046927SAndroid Build Coastguard Worker
1110*61046927SAndroid Build Coastguard Worker for (i = 0; i < MAX_COMBINED_ATOMIC_BUFFERS; i++) {
1111*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx,
1112*61046927SAndroid Build Coastguard Worker &ctx->AtomicBufferBindings[i].BufferObject,
1113*61046927SAndroid Build Coastguard Worker NULL);
1114*61046927SAndroid Build Coastguard Worker ctx->AtomicBufferBindings[i].Offset = 0;
1115*61046927SAndroid Build Coastguard Worker ctx->AtomicBufferBindings[i].Size = 0;
1116*61046927SAndroid Build Coastguard Worker }
1117*61046927SAndroid Build Coastguard Worker }
1118*61046927SAndroid Build Coastguard Worker
1119*61046927SAndroid Build Coastguard Worker /**
1120*61046927SAndroid Build Coastguard Worker * Detach the context from the buffer to re-enable buffer reference counting
1121*61046927SAndroid Build Coastguard Worker * for this context.
1122*61046927SAndroid Build Coastguard Worker */
1123*61046927SAndroid Build Coastguard Worker static void
detach_ctx_from_buffer(struct gl_context * ctx,struct gl_buffer_object * buf)1124*61046927SAndroid Build Coastguard Worker detach_ctx_from_buffer(struct gl_context *ctx, struct gl_buffer_object *buf)
1125*61046927SAndroid Build Coastguard Worker {
1126*61046927SAndroid Build Coastguard Worker assert(buf->Ctx == ctx);
1127*61046927SAndroid Build Coastguard Worker
1128*61046927SAndroid Build Coastguard Worker /* Move private non-atomic context references to the global ref count. */
1129*61046927SAndroid Build Coastguard Worker p_atomic_add(&buf->RefCount, buf->CtxRefCount);
1130*61046927SAndroid Build Coastguard Worker buf->CtxRefCount = 0;
1131*61046927SAndroid Build Coastguard Worker buf->Ctx = NULL;
1132*61046927SAndroid Build Coastguard Worker
1133*61046927SAndroid Build Coastguard Worker /* Remove the context reference where the context holds one
1134*61046927SAndroid Build Coastguard Worker * reference for the lifetime of the buffer ID to skip refcount
1135*61046927SAndroid Build Coastguard Worker * atomics instead of each binding point holding the reference.
1136*61046927SAndroid Build Coastguard Worker */
1137*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &buf, NULL);
1138*61046927SAndroid Build Coastguard Worker }
1139*61046927SAndroid Build Coastguard Worker
1140*61046927SAndroid Build Coastguard Worker /**
1141*61046927SAndroid Build Coastguard Worker * Zombie buffers are buffers that were created by one context and deleted
1142*61046927SAndroid Build Coastguard Worker * by another context. The creating context holds a global reference for each
1143*61046927SAndroid Build Coastguard Worker * buffer it created that can't be unreferenced when another context deletes
1144*61046927SAndroid Build Coastguard Worker * it. Such a buffer becomes a zombie, which means that it's no longer usable
1145*61046927SAndroid Build Coastguard Worker * by OpenGL, but the creating context still holds its global reference of
1146*61046927SAndroid Build Coastguard Worker * the buffer. Only the creating context can remove the reference, which is
1147*61046927SAndroid Build Coastguard Worker * what this function does.
1148*61046927SAndroid Build Coastguard Worker *
1149*61046927SAndroid Build Coastguard Worker * For all zombie buffers, decrement the reference count if the current
1150*61046927SAndroid Build Coastguard Worker * context owns the buffer.
1151*61046927SAndroid Build Coastguard Worker */
1152*61046927SAndroid Build Coastguard Worker static void
unreference_zombie_buffers_for_ctx(struct gl_context * ctx)1153*61046927SAndroid Build Coastguard Worker unreference_zombie_buffers_for_ctx(struct gl_context *ctx)
1154*61046927SAndroid Build Coastguard Worker {
1155*61046927SAndroid Build Coastguard Worker /* It's assumed that the mutex of Shared->BufferObjects is locked. */
1156*61046927SAndroid Build Coastguard Worker set_foreach(ctx->Shared->ZombieBufferObjects, entry) {
1157*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *buf = (struct gl_buffer_object *)entry->key;
1158*61046927SAndroid Build Coastguard Worker
1159*61046927SAndroid Build Coastguard Worker if (buf->Ctx == ctx) {
1160*61046927SAndroid Build Coastguard Worker _mesa_set_remove(ctx->Shared->ZombieBufferObjects, entry);
1161*61046927SAndroid Build Coastguard Worker detach_ctx_from_buffer(ctx, buf);
1162*61046927SAndroid Build Coastguard Worker }
1163*61046927SAndroid Build Coastguard Worker }
1164*61046927SAndroid Build Coastguard Worker }
1165*61046927SAndroid Build Coastguard Worker
1166*61046927SAndroid Build Coastguard Worker /**
1167*61046927SAndroid Build Coastguard Worker * When a context creates buffers, it holds a global buffer reference count
1168*61046927SAndroid Build Coastguard Worker * for each buffer and doesn't update their RefCount. When the context is
1169*61046927SAndroid Build Coastguard Worker * destroyed before the buffers are destroyed, the context must remove
1170*61046927SAndroid Build Coastguard Worker * its global reference from the buffers, so that the buffers can live
1171*61046927SAndroid Build Coastguard Worker * on their own.
1172*61046927SAndroid Build Coastguard Worker *
1173*61046927SAndroid Build Coastguard Worker * At this point, the buffers shouldn't be bound in any bounding point owned
1174*61046927SAndroid Build Coastguard Worker * by the context. (it would crash if they did)
1175*61046927SAndroid Build Coastguard Worker */
1176*61046927SAndroid Build Coastguard Worker static void
detach_unrefcounted_buffer_from_ctx(void * data,void * userData)1177*61046927SAndroid Build Coastguard Worker detach_unrefcounted_buffer_from_ctx(void *data, void *userData)
1178*61046927SAndroid Build Coastguard Worker {
1179*61046927SAndroid Build Coastguard Worker struct gl_context *ctx = (struct gl_context *)userData;
1180*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *buf = (struct gl_buffer_object *)data;
1181*61046927SAndroid Build Coastguard Worker
1182*61046927SAndroid Build Coastguard Worker if (buf->Ctx == ctx) {
1183*61046927SAndroid Build Coastguard Worker /* Detach the current context from live objects. There should be no
1184*61046927SAndroid Build Coastguard Worker * bound buffer in the context at this point, therefore we can just
1185*61046927SAndroid Build Coastguard Worker * unreference the global reference. Other contexts and texture objects
1186*61046927SAndroid Build Coastguard Worker * might still be using the buffer.
1187*61046927SAndroid Build Coastguard Worker */
1188*61046927SAndroid Build Coastguard Worker assert(buf->CtxRefCount == 0);
1189*61046927SAndroid Build Coastguard Worker buf->Ctx = NULL;
1190*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &buf, NULL);
1191*61046927SAndroid Build Coastguard Worker }
1192*61046927SAndroid Build Coastguard Worker }
1193*61046927SAndroid Build Coastguard Worker
1194*61046927SAndroid Build Coastguard Worker void
_mesa_free_buffer_objects(struct gl_context * ctx)1195*61046927SAndroid Build Coastguard Worker _mesa_free_buffer_objects( struct gl_context *ctx )
1196*61046927SAndroid Build Coastguard Worker {
1197*61046927SAndroid Build Coastguard Worker GLuint i;
1198*61046927SAndroid Build Coastguard Worker
1199*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL);
1200*61046927SAndroid Build Coastguard Worker
1201*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->CopyReadBuffer, NULL);
1202*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->CopyWriteBuffer, NULL);
1203*61046927SAndroid Build Coastguard Worker
1204*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, NULL);
1205*61046927SAndroid Build Coastguard Worker
1206*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer, NULL);
1207*61046927SAndroid Build Coastguard Worker
1208*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, NULL);
1209*61046927SAndroid Build Coastguard Worker
1210*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->DrawIndirectBuffer, NULL);
1211*61046927SAndroid Build Coastguard Worker
1212*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->ParameterBuffer, NULL);
1213*61046927SAndroid Build Coastguard Worker
1214*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->DispatchIndirectBuffer, NULL);
1215*61046927SAndroid Build Coastguard Worker
1216*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->QueryBuffer, NULL);
1217*61046927SAndroid Build Coastguard Worker
1218*61046927SAndroid Build Coastguard Worker for (i = 0; i < MAX_COMBINED_UNIFORM_BUFFERS; i++) {
1219*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx,
1220*61046927SAndroid Build Coastguard Worker &ctx->UniformBufferBindings[i].BufferObject,
1221*61046927SAndroid Build Coastguard Worker NULL);
1222*61046927SAndroid Build Coastguard Worker }
1223*61046927SAndroid Build Coastguard Worker
1224*61046927SAndroid Build Coastguard Worker for (i = 0; i < MAX_COMBINED_SHADER_STORAGE_BUFFERS; i++) {
1225*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx,
1226*61046927SAndroid Build Coastguard Worker &ctx->ShaderStorageBufferBindings[i].BufferObject,
1227*61046927SAndroid Build Coastguard Worker NULL);
1228*61046927SAndroid Build Coastguard Worker }
1229*61046927SAndroid Build Coastguard Worker
1230*61046927SAndroid Build Coastguard Worker for (i = 0; i < MAX_COMBINED_ATOMIC_BUFFERS; i++) {
1231*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx,
1232*61046927SAndroid Build Coastguard Worker &ctx->AtomicBufferBindings[i].BufferObject,
1233*61046927SAndroid Build Coastguard Worker NULL);
1234*61046927SAndroid Build Coastguard Worker }
1235*61046927SAndroid Build Coastguard Worker
1236*61046927SAndroid Build Coastguard Worker _mesa_HashLockMutex(&ctx->Shared->BufferObjects);
1237*61046927SAndroid Build Coastguard Worker unreference_zombie_buffers_for_ctx(ctx);
1238*61046927SAndroid Build Coastguard Worker _mesa_HashWalkLocked(&ctx->Shared->BufferObjects,
1239*61046927SAndroid Build Coastguard Worker detach_unrefcounted_buffer_from_ctx, ctx);
1240*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMutex(&ctx->Shared->BufferObjects);
1241*61046927SAndroid Build Coastguard Worker }
1242*61046927SAndroid Build Coastguard Worker
1243*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *
_mesa_bufferobj_alloc(struct gl_context * ctx,GLuint id)1244*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_alloc(struct gl_context *ctx, GLuint id)
1245*61046927SAndroid Build Coastguard Worker {
1246*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *buf = CALLOC_STRUCT(gl_buffer_object);
1247*61046927SAndroid Build Coastguard Worker if (!buf)
1248*61046927SAndroid Build Coastguard Worker return NULL;
1249*61046927SAndroid Build Coastguard Worker
1250*61046927SAndroid Build Coastguard Worker buf->RefCount = 1;
1251*61046927SAndroid Build Coastguard Worker buf->Name = id;
1252*61046927SAndroid Build Coastguard Worker buf->Usage = GL_STATIC_DRAW_ARB;
1253*61046927SAndroid Build Coastguard Worker
1254*61046927SAndroid Build Coastguard Worker simple_mtx_init(&buf->MinMaxCacheMutex, mtx_plain);
1255*61046927SAndroid Build Coastguard Worker if (get_no_minmax_cache())
1256*61046927SAndroid Build Coastguard Worker buf->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE;
1257*61046927SAndroid Build Coastguard Worker return buf;
1258*61046927SAndroid Build Coastguard Worker }
1259*61046927SAndroid Build Coastguard Worker /**
1260*61046927SAndroid Build Coastguard Worker * Create a buffer object that will be backed by an OpenGL buffer ID
1261*61046927SAndroid Build Coastguard Worker * where the creating context will hold one global buffer reference instead
1262*61046927SAndroid Build Coastguard Worker * of updating buffer RefCount for every binding point.
1263*61046927SAndroid Build Coastguard Worker *
1264*61046927SAndroid Build Coastguard Worker * This shouldn't be used for internal buffers.
1265*61046927SAndroid Build Coastguard Worker */
1266*61046927SAndroid Build Coastguard Worker static struct gl_buffer_object *
new_gl_buffer_object(struct gl_context * ctx,GLuint id)1267*61046927SAndroid Build Coastguard Worker new_gl_buffer_object(struct gl_context *ctx, GLuint id)
1268*61046927SAndroid Build Coastguard Worker {
1269*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *buf = _mesa_bufferobj_alloc(ctx, id);
1270*61046927SAndroid Build Coastguard Worker
1271*61046927SAndroid Build Coastguard Worker buf->Ctx = ctx;
1272*61046927SAndroid Build Coastguard Worker buf->RefCount++; /* global buffer reference held by the context */
1273*61046927SAndroid Build Coastguard Worker return buf;
1274*61046927SAndroid Build Coastguard Worker }
1275*61046927SAndroid Build Coastguard Worker
1276*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE bool
handle_bind_buffer_gen(struct gl_context * ctx,GLuint buffer,struct gl_buffer_object ** buf_handle,const char * caller,bool no_error)1277*61046927SAndroid Build Coastguard Worker handle_bind_buffer_gen(struct gl_context *ctx,
1278*61046927SAndroid Build Coastguard Worker GLuint buffer,
1279*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **buf_handle,
1280*61046927SAndroid Build Coastguard Worker const char *caller, bool no_error)
1281*61046927SAndroid Build Coastguard Worker {
1282*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *buf = *buf_handle;
1283*61046927SAndroid Build Coastguard Worker
1284*61046927SAndroid Build Coastguard Worker if (unlikely(!no_error && !buf && _mesa_is_desktop_gl_core(ctx))) {
1285*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller);
1286*61046927SAndroid Build Coastguard Worker return false;
1287*61046927SAndroid Build Coastguard Worker }
1288*61046927SAndroid Build Coastguard Worker
1289*61046927SAndroid Build Coastguard Worker if (unlikely(!buf || buf == &DummyBufferObject)) {
1290*61046927SAndroid Build Coastguard Worker /* If this is a new buffer object id, or one which was generated but
1291*61046927SAndroid Build Coastguard Worker * never used before, allocate a buffer object now.
1292*61046927SAndroid Build Coastguard Worker */
1293*61046927SAndroid Build Coastguard Worker *buf_handle = new_gl_buffer_object(ctx, buffer);
1294*61046927SAndroid Build Coastguard Worker if (!no_error && !*buf_handle) {
1295*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
1296*61046927SAndroid Build Coastguard Worker return false;
1297*61046927SAndroid Build Coastguard Worker }
1298*61046927SAndroid Build Coastguard Worker _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects,
1299*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
1300*61046927SAndroid Build Coastguard Worker _mesa_HashInsertLocked(&ctx->Shared->BufferObjects, buffer,
1301*61046927SAndroid Build Coastguard Worker *buf_handle);
1302*61046927SAndroid Build Coastguard Worker /* If one context only creates buffers and another context only deletes
1303*61046927SAndroid Build Coastguard Worker * buffers, buffers don't get released because it only produces zombie
1304*61046927SAndroid Build Coastguard Worker * buffers. Only the context that has created the buffers can release
1305*61046927SAndroid Build Coastguard Worker * them. Thus, when we create buffers, we prune the list of zombie
1306*61046927SAndroid Build Coastguard Worker * buffers.
1307*61046927SAndroid Build Coastguard Worker */
1308*61046927SAndroid Build Coastguard Worker unreference_zombie_buffers_for_ctx(ctx);
1309*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects,
1310*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
1311*61046927SAndroid Build Coastguard Worker }
1312*61046927SAndroid Build Coastguard Worker
1313*61046927SAndroid Build Coastguard Worker return true;
1314*61046927SAndroid Build Coastguard Worker }
1315*61046927SAndroid Build Coastguard Worker
1316*61046927SAndroid Build Coastguard Worker bool
_mesa_handle_bind_buffer_gen(struct gl_context * ctx,GLuint buffer,struct gl_buffer_object ** buf_handle,const char * caller,bool no_error)1317*61046927SAndroid Build Coastguard Worker _mesa_handle_bind_buffer_gen(struct gl_context *ctx,
1318*61046927SAndroid Build Coastguard Worker GLuint buffer,
1319*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **buf_handle,
1320*61046927SAndroid Build Coastguard Worker const char *caller, bool no_error)
1321*61046927SAndroid Build Coastguard Worker {
1322*61046927SAndroid Build Coastguard Worker return handle_bind_buffer_gen(ctx, buffer, buf_handle, caller, no_error);
1323*61046927SAndroid Build Coastguard Worker }
1324*61046927SAndroid Build Coastguard Worker
1325*61046927SAndroid Build Coastguard Worker /**
1326*61046927SAndroid Build Coastguard Worker * Bind the specified target to buffer for the specified context.
1327*61046927SAndroid Build Coastguard Worker * Called by glBindBuffer() and other functions.
1328*61046927SAndroid Build Coastguard Worker */
1329*61046927SAndroid Build Coastguard Worker static void
bind_buffer_object(struct gl_context * ctx,struct gl_buffer_object ** bindTarget,GLuint buffer,bool no_error)1330*61046927SAndroid Build Coastguard Worker bind_buffer_object(struct gl_context *ctx,
1331*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bindTarget, GLuint buffer,
1332*61046927SAndroid Build Coastguard Worker bool no_error)
1333*61046927SAndroid Build Coastguard Worker {
1334*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *oldBufObj;
1335*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *newBufObj;
1336*61046927SAndroid Build Coastguard Worker
1337*61046927SAndroid Build Coastguard Worker assert(bindTarget);
1338*61046927SAndroid Build Coastguard Worker
1339*61046927SAndroid Build Coastguard Worker /* Fast path that unbinds. It's better when NULL is a literal, so that
1340*61046927SAndroid Build Coastguard Worker * the compiler can simplify this code after inlining.
1341*61046927SAndroid Build Coastguard Worker */
1342*61046927SAndroid Build Coastguard Worker if (buffer == 0) {
1343*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, bindTarget, NULL);
1344*61046927SAndroid Build Coastguard Worker return;
1345*61046927SAndroid Build Coastguard Worker }
1346*61046927SAndroid Build Coastguard Worker
1347*61046927SAndroid Build Coastguard Worker /* Get pointer to old buffer object (to be unbound) */
1348*61046927SAndroid Build Coastguard Worker oldBufObj = *bindTarget;
1349*61046927SAndroid Build Coastguard Worker GLuint old_name = oldBufObj && !oldBufObj->DeletePending ? oldBufObj->Name : 0;
1350*61046927SAndroid Build Coastguard Worker if (unlikely(old_name == buffer))
1351*61046927SAndroid Build Coastguard Worker return; /* rebinding the same buffer object- no change */
1352*61046927SAndroid Build Coastguard Worker
1353*61046927SAndroid Build Coastguard Worker newBufObj = _mesa_lookup_bufferobj(ctx, buffer);
1354*61046927SAndroid Build Coastguard Worker /* Get a new buffer object if it hasn't been created. */
1355*61046927SAndroid Build Coastguard Worker if (unlikely(!handle_bind_buffer_gen(ctx, buffer, &newBufObj, "glBindBuffer",
1356*61046927SAndroid Build Coastguard Worker no_error)))
1357*61046927SAndroid Build Coastguard Worker return;
1358*61046927SAndroid Build Coastguard Worker
1359*61046927SAndroid Build Coastguard Worker /* At this point, the compiler should deduce that newBufObj is non-NULL if
1360*61046927SAndroid Build Coastguard Worker * everything has been inlined, so the compiler should simplify this.
1361*61046927SAndroid Build Coastguard Worker */
1362*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, bindTarget, newBufObj);
1363*61046927SAndroid Build Coastguard Worker }
1364*61046927SAndroid Build Coastguard Worker
1365*61046927SAndroid Build Coastguard Worker
1366*61046927SAndroid Build Coastguard Worker /**
1367*61046927SAndroid Build Coastguard Worker * Update the default buffer objects in the given context to reference those
1368*61046927SAndroid Build Coastguard Worker * specified in the shared state and release those referencing the old
1369*61046927SAndroid Build Coastguard Worker * shared state.
1370*61046927SAndroid Build Coastguard Worker */
1371*61046927SAndroid Build Coastguard Worker void
_mesa_update_default_objects_buffer_objects(struct gl_context * ctx)1372*61046927SAndroid Build Coastguard Worker _mesa_update_default_objects_buffer_objects(struct gl_context *ctx)
1373*61046927SAndroid Build Coastguard Worker {
1374*61046927SAndroid Build Coastguard Worker /* Bind 0 to remove references to those in the shared context hash table. */
1375*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->Array.ArrayBufferObj, 0, false);
1376*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->Array.VAO->IndexBufferObj, 0, false);
1377*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->Pack.BufferObj, 0, false);
1378*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->Unpack.BufferObj, 0, false);
1379*61046927SAndroid Build Coastguard Worker }
1380*61046927SAndroid Build Coastguard Worker
1381*61046927SAndroid Build Coastguard Worker
1382*61046927SAndroid Build Coastguard Worker
1383*61046927SAndroid Build Coastguard Worker /**
1384*61046927SAndroid Build Coastguard Worker * Return the gl_buffer_object for the given ID.
1385*61046927SAndroid Build Coastguard Worker * Always return NULL for ID 0.
1386*61046927SAndroid Build Coastguard Worker */
1387*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *
_mesa_lookup_bufferobj(struct gl_context * ctx,GLuint buffer)1388*61046927SAndroid Build Coastguard Worker _mesa_lookup_bufferobj(struct gl_context *ctx, GLuint buffer)
1389*61046927SAndroid Build Coastguard Worker {
1390*61046927SAndroid Build Coastguard Worker if (buffer == 0)
1391*61046927SAndroid Build Coastguard Worker return NULL;
1392*61046927SAndroid Build Coastguard Worker else
1393*61046927SAndroid Build Coastguard Worker return (struct gl_buffer_object *)
1394*61046927SAndroid Build Coastguard Worker _mesa_HashLookupMaybeLocked(&ctx->Shared->BufferObjects, buffer,
1395*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
1396*61046927SAndroid Build Coastguard Worker }
1397*61046927SAndroid Build Coastguard Worker
1398*61046927SAndroid Build Coastguard Worker
1399*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *
_mesa_lookup_bufferobj_locked(struct gl_context * ctx,GLuint buffer)1400*61046927SAndroid Build Coastguard Worker _mesa_lookup_bufferobj_locked(struct gl_context *ctx, GLuint buffer)
1401*61046927SAndroid Build Coastguard Worker {
1402*61046927SAndroid Build Coastguard Worker if (buffer == 0)
1403*61046927SAndroid Build Coastguard Worker return NULL;
1404*61046927SAndroid Build Coastguard Worker else
1405*61046927SAndroid Build Coastguard Worker return (struct gl_buffer_object *)
1406*61046927SAndroid Build Coastguard Worker _mesa_HashLookupLocked(&ctx->Shared->BufferObjects, buffer);
1407*61046927SAndroid Build Coastguard Worker }
1408*61046927SAndroid Build Coastguard Worker
1409*61046927SAndroid Build Coastguard Worker /**
1410*61046927SAndroid Build Coastguard Worker * A convenience function for direct state access functions that throws
1411*61046927SAndroid Build Coastguard Worker * GL_INVALID_OPERATION if buffer is not the name of an existing
1412*61046927SAndroid Build Coastguard Worker * buffer object.
1413*61046927SAndroid Build Coastguard Worker */
1414*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *
_mesa_lookup_bufferobj_err(struct gl_context * ctx,GLuint buffer,const char * caller)1415*61046927SAndroid Build Coastguard Worker _mesa_lookup_bufferobj_err(struct gl_context *ctx, GLuint buffer,
1416*61046927SAndroid Build Coastguard Worker const char *caller)
1417*61046927SAndroid Build Coastguard Worker {
1418*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
1419*61046927SAndroid Build Coastguard Worker
1420*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
1421*61046927SAndroid Build Coastguard Worker if (!bufObj || bufObj == &DummyBufferObject) {
1422*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
1423*61046927SAndroid Build Coastguard Worker "%s(non-existent buffer object %u)", caller, buffer);
1424*61046927SAndroid Build Coastguard Worker return NULL;
1425*61046927SAndroid Build Coastguard Worker }
1426*61046927SAndroid Build Coastguard Worker
1427*61046927SAndroid Build Coastguard Worker return bufObj;
1428*61046927SAndroid Build Coastguard Worker }
1429*61046927SAndroid Build Coastguard Worker
1430*61046927SAndroid Build Coastguard Worker
1431*61046927SAndroid Build Coastguard Worker /**
1432*61046927SAndroid Build Coastguard Worker * Look up a buffer object for a multi-bind function.
1433*61046927SAndroid Build Coastguard Worker *
1434*61046927SAndroid Build Coastguard Worker * Unlike _mesa_lookup_bufferobj(), this function also takes care
1435*61046927SAndroid Build Coastguard Worker * of generating an error if the buffer ID is not zero or the name
1436*61046927SAndroid Build Coastguard Worker * of an existing buffer object.
1437*61046927SAndroid Build Coastguard Worker *
1438*61046927SAndroid Build Coastguard Worker * If the buffer ID refers to an existing buffer object, a pointer
1439*61046927SAndroid Build Coastguard Worker * to the buffer object is returned. If the ID is zero, NULL is returned.
1440*61046927SAndroid Build Coastguard Worker * If the ID is not zero and does not refer to a valid buffer object, this
1441*61046927SAndroid Build Coastguard Worker * function returns NULL.
1442*61046927SAndroid Build Coastguard Worker *
1443*61046927SAndroid Build Coastguard Worker * This function assumes that the caller has already locked the
1444*61046927SAndroid Build Coastguard Worker * hash table mutex by calling
1445*61046927SAndroid Build Coastguard Worker * _mesa_HashLockMutex(&ctx->Shared->BufferObjects).
1446*61046927SAndroid Build Coastguard Worker */
1447*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *
_mesa_multi_bind_lookup_bufferobj(struct gl_context * ctx,const GLuint * buffers,GLuint index,const char * caller,bool * error)1448*61046927SAndroid Build Coastguard Worker _mesa_multi_bind_lookup_bufferobj(struct gl_context *ctx,
1449*61046927SAndroid Build Coastguard Worker const GLuint *buffers,
1450*61046927SAndroid Build Coastguard Worker GLuint index, const char *caller,
1451*61046927SAndroid Build Coastguard Worker bool *error)
1452*61046927SAndroid Build Coastguard Worker {
1453*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = NULL;
1454*61046927SAndroid Build Coastguard Worker
1455*61046927SAndroid Build Coastguard Worker *error = false;
1456*61046927SAndroid Build Coastguard Worker
1457*61046927SAndroid Build Coastguard Worker if (buffers[index] != 0) {
1458*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_locked(ctx, buffers[index]);
1459*61046927SAndroid Build Coastguard Worker
1460*61046927SAndroid Build Coastguard Worker /* The multi-bind functions don't create the buffer objects
1461*61046927SAndroid Build Coastguard Worker when they don't exist. */
1462*61046927SAndroid Build Coastguard Worker if (bufObj == &DummyBufferObject)
1463*61046927SAndroid Build Coastguard Worker bufObj = NULL;
1464*61046927SAndroid Build Coastguard Worker
1465*61046927SAndroid Build Coastguard Worker if (!bufObj) {
1466*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
1467*61046927SAndroid Build Coastguard Worker *
1468*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if any value
1469*61046927SAndroid Build Coastguard Worker * in <buffers> is not zero or the name of an existing
1470*61046927SAndroid Build Coastguard Worker * buffer object (per binding)."
1471*61046927SAndroid Build Coastguard Worker */
1472*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
1473*61046927SAndroid Build Coastguard Worker "%s(buffers[%u]=%u is not zero or the name "
1474*61046927SAndroid Build Coastguard Worker "of an existing buffer object)",
1475*61046927SAndroid Build Coastguard Worker caller, index, buffers[index]);
1476*61046927SAndroid Build Coastguard Worker *error = true;
1477*61046927SAndroid Build Coastguard Worker }
1478*61046927SAndroid Build Coastguard Worker }
1479*61046927SAndroid Build Coastguard Worker
1480*61046927SAndroid Build Coastguard Worker return bufObj;
1481*61046927SAndroid Build Coastguard Worker }
1482*61046927SAndroid Build Coastguard Worker
1483*61046927SAndroid Build Coastguard Worker
1484*61046927SAndroid Build Coastguard Worker /**
1485*61046927SAndroid Build Coastguard Worker * If *ptr points to obj, set ptr = the Null/default buffer object.
1486*61046927SAndroid Build Coastguard Worker * This is a helper for buffer object deletion.
1487*61046927SAndroid Build Coastguard Worker * The GL spec says that deleting a buffer object causes it to get
1488*61046927SAndroid Build Coastguard Worker * unbound from all arrays in the current context.
1489*61046927SAndroid Build Coastguard Worker */
1490*61046927SAndroid Build Coastguard Worker static void
unbind(struct gl_context * ctx,struct gl_vertex_array_object * vao,unsigned index,struct gl_buffer_object * obj)1491*61046927SAndroid Build Coastguard Worker unbind(struct gl_context *ctx,
1492*61046927SAndroid Build Coastguard Worker struct gl_vertex_array_object *vao, unsigned index,
1493*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *obj)
1494*61046927SAndroid Build Coastguard Worker {
1495*61046927SAndroid Build Coastguard Worker if (vao->BufferBinding[index].BufferObj == obj) {
1496*61046927SAndroid Build Coastguard Worker _mesa_bind_vertex_buffer(ctx, vao, index, NULL,
1497*61046927SAndroid Build Coastguard Worker vao->BufferBinding[index].Offset,
1498*61046927SAndroid Build Coastguard Worker vao->BufferBinding[index].Stride, true, false);
1499*61046927SAndroid Build Coastguard Worker }
1500*61046927SAndroid Build Coastguard Worker }
1501*61046927SAndroid Build Coastguard Worker
1502*61046927SAndroid Build Coastguard Worker void
_mesa_buffer_unmap_all_mappings(struct gl_context * ctx,struct gl_buffer_object * bufObj)1503*61046927SAndroid Build Coastguard Worker _mesa_buffer_unmap_all_mappings(struct gl_context *ctx,
1504*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj)
1505*61046927SAndroid Build Coastguard Worker {
1506*61046927SAndroid Build Coastguard Worker for (int i = 0; i < MAP_COUNT; i++) {
1507*61046927SAndroid Build Coastguard Worker if (_mesa_bufferobj_mapped(bufObj, i)) {
1508*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_unmap(ctx, bufObj, i);
1509*61046927SAndroid Build Coastguard Worker assert(bufObj->Mappings[i].Pointer == NULL);
1510*61046927SAndroid Build Coastguard Worker bufObj->Mappings[i].AccessFlags = 0;
1511*61046927SAndroid Build Coastguard Worker }
1512*61046927SAndroid Build Coastguard Worker }
1513*61046927SAndroid Build Coastguard Worker }
1514*61046927SAndroid Build Coastguard Worker
1515*61046927SAndroid Build Coastguard Worker
1516*61046927SAndroid Build Coastguard Worker /**********************************************************************/
1517*61046927SAndroid Build Coastguard Worker /* API Functions */
1518*61046927SAndroid Build Coastguard Worker /**********************************************************************/
1519*61046927SAndroid Build Coastguard Worker
1520*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindBuffer_no_error(GLenum target,GLuint buffer)1521*61046927SAndroid Build Coastguard Worker _mesa_BindBuffer_no_error(GLenum target, GLuint buffer)
1522*61046927SAndroid Build Coastguard Worker {
1523*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1524*61046927SAndroid Build Coastguard Worker
1525*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bindTarget = get_buffer_target(ctx, target, true);
1526*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, bindTarget, buffer, true);
1527*61046927SAndroid Build Coastguard Worker }
1528*61046927SAndroid Build Coastguard Worker
1529*61046927SAndroid Build Coastguard Worker
1530*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindBuffer(GLenum target,GLuint buffer)1531*61046927SAndroid Build Coastguard Worker _mesa_BindBuffer(GLenum target, GLuint buffer)
1532*61046927SAndroid Build Coastguard Worker {
1533*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1534*61046927SAndroid Build Coastguard Worker
1535*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API) {
1536*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glBindBuffer(%s, %u)\n",
1537*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target), buffer);
1538*61046927SAndroid Build Coastguard Worker }
1539*61046927SAndroid Build Coastguard Worker
1540*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bindTarget = get_buffer_target(ctx, target, false);
1541*61046927SAndroid Build Coastguard Worker if (!bindTarget) {
1542*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target %s)",
1543*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
1544*61046927SAndroid Build Coastguard Worker return;
1545*61046927SAndroid Build Coastguard Worker }
1546*61046927SAndroid Build Coastguard Worker
1547*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, bindTarget, buffer, false);
1548*61046927SAndroid Build Coastguard Worker }
1549*61046927SAndroid Build Coastguard Worker
1550*61046927SAndroid Build Coastguard Worker /**
1551*61046927SAndroid Build Coastguard Worker * Binds a buffer object to a binding point.
1552*61046927SAndroid Build Coastguard Worker *
1553*61046927SAndroid Build Coastguard Worker * The caller is responsible for validating the offset,
1554*61046927SAndroid Build Coastguard Worker * flushing the vertices and updating NewDriverState.
1555*61046927SAndroid Build Coastguard Worker */
1556*61046927SAndroid Build Coastguard Worker static void
set_buffer_binding(struct gl_context * ctx,struct gl_buffer_binding * binding,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,bool autoSize,gl_buffer_usage usage)1557*61046927SAndroid Build Coastguard Worker set_buffer_binding(struct gl_context *ctx,
1558*61046927SAndroid Build Coastguard Worker struct gl_buffer_binding *binding,
1559*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
1560*61046927SAndroid Build Coastguard Worker GLintptr offset,
1561*61046927SAndroid Build Coastguard Worker GLsizeiptr size,
1562*61046927SAndroid Build Coastguard Worker bool autoSize, gl_buffer_usage usage)
1563*61046927SAndroid Build Coastguard Worker {
1564*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &binding->BufferObject, bufObj);
1565*61046927SAndroid Build Coastguard Worker
1566*61046927SAndroid Build Coastguard Worker binding->Offset = offset;
1567*61046927SAndroid Build Coastguard Worker binding->Size = size;
1568*61046927SAndroid Build Coastguard Worker binding->AutomaticSize = autoSize;
1569*61046927SAndroid Build Coastguard Worker
1570*61046927SAndroid Build Coastguard Worker /* If this is a real buffer object, mark it has having been used
1571*61046927SAndroid Build Coastguard Worker * at some point as an atomic counter buffer.
1572*61046927SAndroid Build Coastguard Worker */
1573*61046927SAndroid Build Coastguard Worker if (size >= 0)
1574*61046927SAndroid Build Coastguard Worker bufObj->UsageHistory |= usage;
1575*61046927SAndroid Build Coastguard Worker }
1576*61046927SAndroid Build Coastguard Worker
1577*61046927SAndroid Build Coastguard Worker static void
set_buffer_multi_binding(struct gl_context * ctx,const GLuint * buffers,int idx,const char * caller,struct gl_buffer_binding * binding,GLintptr offset,GLsizeiptr size,bool range,gl_buffer_usage usage)1578*61046927SAndroid Build Coastguard Worker set_buffer_multi_binding(struct gl_context *ctx,
1579*61046927SAndroid Build Coastguard Worker const GLuint *buffers,
1580*61046927SAndroid Build Coastguard Worker int idx,
1581*61046927SAndroid Build Coastguard Worker const char *caller,
1582*61046927SAndroid Build Coastguard Worker struct gl_buffer_binding *binding,
1583*61046927SAndroid Build Coastguard Worker GLintptr offset,
1584*61046927SAndroid Build Coastguard Worker GLsizeiptr size,
1585*61046927SAndroid Build Coastguard Worker bool range,
1586*61046927SAndroid Build Coastguard Worker gl_buffer_usage usage)
1587*61046927SAndroid Build Coastguard Worker {
1588*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
1589*61046927SAndroid Build Coastguard Worker
1590*61046927SAndroid Build Coastguard Worker if (binding->BufferObject && binding->BufferObject->Name == buffers[idx])
1591*61046927SAndroid Build Coastguard Worker bufObj = binding->BufferObject;
1592*61046927SAndroid Build Coastguard Worker else {
1593*61046927SAndroid Build Coastguard Worker bool error;
1594*61046927SAndroid Build Coastguard Worker bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, idx, caller,
1595*61046927SAndroid Build Coastguard Worker &error);
1596*61046927SAndroid Build Coastguard Worker if (error)
1597*61046927SAndroid Build Coastguard Worker return;
1598*61046927SAndroid Build Coastguard Worker }
1599*61046927SAndroid Build Coastguard Worker
1600*61046927SAndroid Build Coastguard Worker if (!bufObj)
1601*61046927SAndroid Build Coastguard Worker set_buffer_binding(ctx, binding, bufObj, -1, -1, !range, usage);
1602*61046927SAndroid Build Coastguard Worker else
1603*61046927SAndroid Build Coastguard Worker set_buffer_binding(ctx, binding, bufObj, offset, size, !range, usage);
1604*61046927SAndroid Build Coastguard Worker }
1605*61046927SAndroid Build Coastguard Worker
1606*61046927SAndroid Build Coastguard Worker static void
bind_buffer(struct gl_context * ctx,struct gl_buffer_binding * binding,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,GLboolean autoSize,uint64_t driver_state,gl_buffer_usage usage)1607*61046927SAndroid Build Coastguard Worker bind_buffer(struct gl_context *ctx,
1608*61046927SAndroid Build Coastguard Worker struct gl_buffer_binding *binding,
1609*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
1610*61046927SAndroid Build Coastguard Worker GLintptr offset,
1611*61046927SAndroid Build Coastguard Worker GLsizeiptr size,
1612*61046927SAndroid Build Coastguard Worker GLboolean autoSize,
1613*61046927SAndroid Build Coastguard Worker uint64_t driver_state,
1614*61046927SAndroid Build Coastguard Worker gl_buffer_usage usage)
1615*61046927SAndroid Build Coastguard Worker {
1616*61046927SAndroid Build Coastguard Worker if (binding->BufferObject == bufObj &&
1617*61046927SAndroid Build Coastguard Worker binding->Offset == offset &&
1618*61046927SAndroid Build Coastguard Worker binding->Size == size &&
1619*61046927SAndroid Build Coastguard Worker binding->AutomaticSize == autoSize) {
1620*61046927SAndroid Build Coastguard Worker return;
1621*61046927SAndroid Build Coastguard Worker }
1622*61046927SAndroid Build Coastguard Worker
1623*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
1624*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= driver_state;
1625*61046927SAndroid Build Coastguard Worker
1626*61046927SAndroid Build Coastguard Worker set_buffer_binding(ctx, binding, bufObj, offset, size, autoSize, usage);
1627*61046927SAndroid Build Coastguard Worker }
1628*61046927SAndroid Build Coastguard Worker
1629*61046927SAndroid Build Coastguard Worker /**
1630*61046927SAndroid Build Coastguard Worker * Binds a buffer object to a uniform buffer binding point.
1631*61046927SAndroid Build Coastguard Worker *
1632*61046927SAndroid Build Coastguard Worker * Unlike set_buffer_binding(), this function also flushes vertices
1633*61046927SAndroid Build Coastguard Worker * and updates NewDriverState. It also checks if the binding
1634*61046927SAndroid Build Coastguard Worker * has actually changed before updating it.
1635*61046927SAndroid Build Coastguard Worker */
1636*61046927SAndroid Build Coastguard Worker static void
bind_uniform_buffer(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,GLboolean autoSize)1637*61046927SAndroid Build Coastguard Worker bind_uniform_buffer(struct gl_context *ctx,
1638*61046927SAndroid Build Coastguard Worker GLuint index,
1639*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
1640*61046927SAndroid Build Coastguard Worker GLintptr offset,
1641*61046927SAndroid Build Coastguard Worker GLsizeiptr size,
1642*61046927SAndroid Build Coastguard Worker GLboolean autoSize)
1643*61046927SAndroid Build Coastguard Worker {
1644*61046927SAndroid Build Coastguard Worker bind_buffer(ctx, &ctx->UniformBufferBindings[index],
1645*61046927SAndroid Build Coastguard Worker bufObj, offset, size, autoSize,
1646*61046927SAndroid Build Coastguard Worker ST_NEW_UNIFORM_BUFFER,
1647*61046927SAndroid Build Coastguard Worker USAGE_UNIFORM_BUFFER);
1648*61046927SAndroid Build Coastguard Worker }
1649*61046927SAndroid Build Coastguard Worker
1650*61046927SAndroid Build Coastguard Worker /**
1651*61046927SAndroid Build Coastguard Worker * Binds a buffer object to a shader storage buffer binding point.
1652*61046927SAndroid Build Coastguard Worker *
1653*61046927SAndroid Build Coastguard Worker * Unlike set_ssbo_binding(), this function also flushes vertices
1654*61046927SAndroid Build Coastguard Worker * and updates NewDriverState. It also checks if the binding
1655*61046927SAndroid Build Coastguard Worker * has actually changed before updating it.
1656*61046927SAndroid Build Coastguard Worker */
1657*61046927SAndroid Build Coastguard Worker static void
bind_shader_storage_buffer(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,GLboolean autoSize)1658*61046927SAndroid Build Coastguard Worker bind_shader_storage_buffer(struct gl_context *ctx,
1659*61046927SAndroid Build Coastguard Worker GLuint index,
1660*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
1661*61046927SAndroid Build Coastguard Worker GLintptr offset,
1662*61046927SAndroid Build Coastguard Worker GLsizeiptr size,
1663*61046927SAndroid Build Coastguard Worker GLboolean autoSize)
1664*61046927SAndroid Build Coastguard Worker {
1665*61046927SAndroid Build Coastguard Worker bind_buffer(ctx, &ctx->ShaderStorageBufferBindings[index],
1666*61046927SAndroid Build Coastguard Worker bufObj, offset, size, autoSize,
1667*61046927SAndroid Build Coastguard Worker ST_NEW_STORAGE_BUFFER,
1668*61046927SAndroid Build Coastguard Worker USAGE_SHADER_STORAGE_BUFFER);
1669*61046927SAndroid Build Coastguard Worker }
1670*61046927SAndroid Build Coastguard Worker
1671*61046927SAndroid Build Coastguard Worker /**
1672*61046927SAndroid Build Coastguard Worker * Binds a buffer object to an atomic buffer binding point.
1673*61046927SAndroid Build Coastguard Worker *
1674*61046927SAndroid Build Coastguard Worker * Unlike set_atomic_binding(), this function also flushes vertices
1675*61046927SAndroid Build Coastguard Worker * and updates NewDriverState. It also checks if the binding
1676*61046927SAndroid Build Coastguard Worker * has actually changed before updating it.
1677*61046927SAndroid Build Coastguard Worker */
1678*61046927SAndroid Build Coastguard Worker static void
bind_atomic_buffer(struct gl_context * ctx,unsigned index,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,GLboolean autoSize)1679*61046927SAndroid Build Coastguard Worker bind_atomic_buffer(struct gl_context *ctx, unsigned index,
1680*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj, GLintptr offset,
1681*61046927SAndroid Build Coastguard Worker GLsizeiptr size, GLboolean autoSize)
1682*61046927SAndroid Build Coastguard Worker {
1683*61046927SAndroid Build Coastguard Worker bind_buffer(ctx, &ctx->AtomicBufferBindings[index],
1684*61046927SAndroid Build Coastguard Worker bufObj, offset, size, autoSize,
1685*61046927SAndroid Build Coastguard Worker ctx->DriverFlags.NewAtomicBuffer,
1686*61046927SAndroid Build Coastguard Worker USAGE_ATOMIC_COUNTER_BUFFER);
1687*61046927SAndroid Build Coastguard Worker }
1688*61046927SAndroid Build Coastguard Worker
1689*61046927SAndroid Build Coastguard Worker /**
1690*61046927SAndroid Build Coastguard Worker * Bind a buffer object to a uniform block binding point.
1691*61046927SAndroid Build Coastguard Worker * As above, but offset = 0.
1692*61046927SAndroid Build Coastguard Worker */
1693*61046927SAndroid Build Coastguard Worker static void
bind_buffer_base_uniform_buffer(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj)1694*61046927SAndroid Build Coastguard Worker bind_buffer_base_uniform_buffer(struct gl_context *ctx,
1695*61046927SAndroid Build Coastguard Worker GLuint index,
1696*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj)
1697*61046927SAndroid Build Coastguard Worker {
1698*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.MaxUniformBufferBindings) {
1699*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
1700*61046927SAndroid Build Coastguard Worker return;
1701*61046927SAndroid Build Coastguard Worker }
1702*61046927SAndroid Build Coastguard Worker
1703*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, bufObj);
1704*61046927SAndroid Build Coastguard Worker
1705*61046927SAndroid Build Coastguard Worker if (!bufObj)
1706*61046927SAndroid Build Coastguard Worker bind_uniform_buffer(ctx, index, bufObj, -1, -1, GL_TRUE);
1707*61046927SAndroid Build Coastguard Worker else
1708*61046927SAndroid Build Coastguard Worker bind_uniform_buffer(ctx, index, bufObj, 0, 0, GL_TRUE);
1709*61046927SAndroid Build Coastguard Worker }
1710*61046927SAndroid Build Coastguard Worker
1711*61046927SAndroid Build Coastguard Worker /**
1712*61046927SAndroid Build Coastguard Worker * Bind a buffer object to a shader storage block binding point.
1713*61046927SAndroid Build Coastguard Worker * As above, but offset = 0.
1714*61046927SAndroid Build Coastguard Worker */
1715*61046927SAndroid Build Coastguard Worker static void
bind_buffer_base_shader_storage_buffer(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj)1716*61046927SAndroid Build Coastguard Worker bind_buffer_base_shader_storage_buffer(struct gl_context *ctx,
1717*61046927SAndroid Build Coastguard Worker GLuint index,
1718*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj)
1719*61046927SAndroid Build Coastguard Worker {
1720*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.MaxShaderStorageBufferBindings) {
1721*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
1722*61046927SAndroid Build Coastguard Worker return;
1723*61046927SAndroid Build Coastguard Worker }
1724*61046927SAndroid Build Coastguard Worker
1725*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer, bufObj);
1726*61046927SAndroid Build Coastguard Worker
1727*61046927SAndroid Build Coastguard Worker if (!bufObj)
1728*61046927SAndroid Build Coastguard Worker bind_shader_storage_buffer(ctx, index, bufObj, -1, -1, GL_TRUE);
1729*61046927SAndroid Build Coastguard Worker else
1730*61046927SAndroid Build Coastguard Worker bind_shader_storage_buffer(ctx, index, bufObj, 0, 0, GL_TRUE);
1731*61046927SAndroid Build Coastguard Worker }
1732*61046927SAndroid Build Coastguard Worker
1733*61046927SAndroid Build Coastguard Worker /**
1734*61046927SAndroid Build Coastguard Worker * Bind a buffer object to a shader storage block binding point.
1735*61046927SAndroid Build Coastguard Worker * As above, but offset = 0.
1736*61046927SAndroid Build Coastguard Worker */
1737*61046927SAndroid Build Coastguard Worker static void
bind_buffer_base_atomic_buffer(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj)1738*61046927SAndroid Build Coastguard Worker bind_buffer_base_atomic_buffer(struct gl_context *ctx,
1739*61046927SAndroid Build Coastguard Worker GLuint index,
1740*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj)
1741*61046927SAndroid Build Coastguard Worker {
1742*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.MaxAtomicBufferBindings) {
1743*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferBase(index=%d)", index);
1744*61046927SAndroid Build Coastguard Worker return;
1745*61046927SAndroid Build Coastguard Worker }
1746*61046927SAndroid Build Coastguard Worker
1747*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
1748*61046927SAndroid Build Coastguard Worker
1749*61046927SAndroid Build Coastguard Worker if (!bufObj)
1750*61046927SAndroid Build Coastguard Worker bind_atomic_buffer(ctx, index, bufObj, -1, -1, GL_TRUE);
1751*61046927SAndroid Build Coastguard Worker else
1752*61046927SAndroid Build Coastguard Worker bind_atomic_buffer(ctx, index, bufObj, 0, 0, GL_TRUE);
1753*61046927SAndroid Build Coastguard Worker }
1754*61046927SAndroid Build Coastguard Worker
1755*61046927SAndroid Build Coastguard Worker /**
1756*61046927SAndroid Build Coastguard Worker * Delete a set of buffer objects.
1757*61046927SAndroid Build Coastguard Worker *
1758*61046927SAndroid Build Coastguard Worker * \param n Number of buffer objects to delete.
1759*61046927SAndroid Build Coastguard Worker * \param ids Array of \c n buffer object IDs.
1760*61046927SAndroid Build Coastguard Worker */
1761*61046927SAndroid Build Coastguard Worker static void
delete_buffers(struct gl_context * ctx,GLsizei n,const GLuint * ids)1762*61046927SAndroid Build Coastguard Worker delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids)
1763*61046927SAndroid Build Coastguard Worker {
1764*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
1765*61046927SAndroid Build Coastguard Worker
1766*61046927SAndroid Build Coastguard Worker _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects,
1767*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
1768*61046927SAndroid Build Coastguard Worker unreference_zombie_buffers_for_ctx(ctx);
1769*61046927SAndroid Build Coastguard Worker
1770*61046927SAndroid Build Coastguard Worker for (GLsizei i = 0; i < n; i++) {
1771*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj =
1772*61046927SAndroid Build Coastguard Worker _mesa_lookup_bufferobj_locked(ctx, ids[i]);
1773*61046927SAndroid Build Coastguard Worker if (bufObj) {
1774*61046927SAndroid Build Coastguard Worker struct gl_vertex_array_object *vao = ctx->Array.VAO;
1775*61046927SAndroid Build Coastguard Worker GLuint j;
1776*61046927SAndroid Build Coastguard Worker
1777*61046927SAndroid Build Coastguard Worker assert(bufObj->Name == ids[i] || bufObj == &DummyBufferObject);
1778*61046927SAndroid Build Coastguard Worker
1779*61046927SAndroid Build Coastguard Worker _mesa_buffer_unmap_all_mappings(ctx, bufObj);
1780*61046927SAndroid Build Coastguard Worker
1781*61046927SAndroid Build Coastguard Worker /* unbind any vertex pointers bound to this buffer */
1782*61046927SAndroid Build Coastguard Worker for (j = 0; j < ARRAY_SIZE(vao->BufferBinding); j++) {
1783*61046927SAndroid Build Coastguard Worker unbind(ctx, vao, j, bufObj);
1784*61046927SAndroid Build Coastguard Worker }
1785*61046927SAndroid Build Coastguard Worker
1786*61046927SAndroid Build Coastguard Worker if (ctx->Array.ArrayBufferObj == bufObj) {
1787*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->Array.ArrayBufferObj, 0, false);
1788*61046927SAndroid Build Coastguard Worker }
1789*61046927SAndroid Build Coastguard Worker if (vao->IndexBufferObj == bufObj) {
1790*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &vao->IndexBufferObj, 0, false);
1791*61046927SAndroid Build Coastguard Worker }
1792*61046927SAndroid Build Coastguard Worker
1793*61046927SAndroid Build Coastguard Worker /* unbind ARB_draw_indirect binding point */
1794*61046927SAndroid Build Coastguard Worker if (ctx->DrawIndirectBuffer == bufObj) {
1795*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->DrawIndirectBuffer, 0, false);
1796*61046927SAndroid Build Coastguard Worker }
1797*61046927SAndroid Build Coastguard Worker
1798*61046927SAndroid Build Coastguard Worker /* unbind ARB_indirect_parameters binding point */
1799*61046927SAndroid Build Coastguard Worker if (ctx->ParameterBuffer == bufObj) {
1800*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->ParameterBuffer, 0, false);
1801*61046927SAndroid Build Coastguard Worker }
1802*61046927SAndroid Build Coastguard Worker
1803*61046927SAndroid Build Coastguard Worker /* unbind ARB_compute_shader binding point */
1804*61046927SAndroid Build Coastguard Worker if (ctx->DispatchIndirectBuffer == bufObj) {
1805*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->DispatchIndirectBuffer, 0, false);
1806*61046927SAndroid Build Coastguard Worker }
1807*61046927SAndroid Build Coastguard Worker
1808*61046927SAndroid Build Coastguard Worker /* unbind ARB_copy_buffer binding points */
1809*61046927SAndroid Build Coastguard Worker if (ctx->CopyReadBuffer == bufObj) {
1810*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->CopyReadBuffer, 0, false);
1811*61046927SAndroid Build Coastguard Worker }
1812*61046927SAndroid Build Coastguard Worker if (ctx->CopyWriteBuffer == bufObj) {
1813*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->CopyWriteBuffer, 0, false);
1814*61046927SAndroid Build Coastguard Worker }
1815*61046927SAndroid Build Coastguard Worker
1816*61046927SAndroid Build Coastguard Worker /* unbind transform feedback binding points */
1817*61046927SAndroid Build Coastguard Worker if (ctx->TransformFeedback.CurrentBuffer == bufObj) {
1818*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->TransformFeedback.CurrentBuffer, 0, false);
1819*61046927SAndroid Build Coastguard Worker }
1820*61046927SAndroid Build Coastguard Worker for (j = 0; j < MAX_FEEDBACK_BUFFERS; j++) {
1821*61046927SAndroid Build Coastguard Worker if (ctx->TransformFeedback.CurrentObject->Buffers[j] == bufObj) {
1822*61046927SAndroid Build Coastguard Worker _mesa_bind_buffer_base_transform_feedback(ctx,
1823*61046927SAndroid Build Coastguard Worker ctx->TransformFeedback.CurrentObject,
1824*61046927SAndroid Build Coastguard Worker j, NULL, false);
1825*61046927SAndroid Build Coastguard Worker }
1826*61046927SAndroid Build Coastguard Worker }
1827*61046927SAndroid Build Coastguard Worker
1828*61046927SAndroid Build Coastguard Worker /* unbind UBO binding points */
1829*61046927SAndroid Build Coastguard Worker for (j = 0; j < ctx->Const.MaxUniformBufferBindings; j++) {
1830*61046927SAndroid Build Coastguard Worker if (ctx->UniformBufferBindings[j].BufferObject == bufObj) {
1831*61046927SAndroid Build Coastguard Worker bind_buffer_base_uniform_buffer(ctx, j, NULL);
1832*61046927SAndroid Build Coastguard Worker }
1833*61046927SAndroid Build Coastguard Worker }
1834*61046927SAndroid Build Coastguard Worker
1835*61046927SAndroid Build Coastguard Worker if (ctx->UniformBuffer == bufObj) {
1836*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->UniformBuffer, 0, false);
1837*61046927SAndroid Build Coastguard Worker }
1838*61046927SAndroid Build Coastguard Worker
1839*61046927SAndroid Build Coastguard Worker /* unbind SSBO binding points */
1840*61046927SAndroid Build Coastguard Worker for (j = 0; j < ctx->Const.MaxShaderStorageBufferBindings; j++) {
1841*61046927SAndroid Build Coastguard Worker if (ctx->ShaderStorageBufferBindings[j].BufferObject == bufObj) {
1842*61046927SAndroid Build Coastguard Worker bind_buffer_base_shader_storage_buffer(ctx, j, NULL);
1843*61046927SAndroid Build Coastguard Worker }
1844*61046927SAndroid Build Coastguard Worker }
1845*61046927SAndroid Build Coastguard Worker
1846*61046927SAndroid Build Coastguard Worker if (ctx->ShaderStorageBuffer == bufObj) {
1847*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->ShaderStorageBuffer, 0, false);
1848*61046927SAndroid Build Coastguard Worker }
1849*61046927SAndroid Build Coastguard Worker
1850*61046927SAndroid Build Coastguard Worker /* unbind Atomci Buffer binding points */
1851*61046927SAndroid Build Coastguard Worker for (j = 0; j < ctx->Const.MaxAtomicBufferBindings; j++) {
1852*61046927SAndroid Build Coastguard Worker if (ctx->AtomicBufferBindings[j].BufferObject == bufObj) {
1853*61046927SAndroid Build Coastguard Worker bind_buffer_base_atomic_buffer(ctx, j, NULL);
1854*61046927SAndroid Build Coastguard Worker }
1855*61046927SAndroid Build Coastguard Worker }
1856*61046927SAndroid Build Coastguard Worker
1857*61046927SAndroid Build Coastguard Worker if (ctx->AtomicBuffer == bufObj) {
1858*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->AtomicBuffer, 0, false);
1859*61046927SAndroid Build Coastguard Worker }
1860*61046927SAndroid Build Coastguard Worker
1861*61046927SAndroid Build Coastguard Worker /* unbind any pixel pack/unpack pointers bound to this buffer */
1862*61046927SAndroid Build Coastguard Worker if (ctx->Pack.BufferObj == bufObj) {
1863*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->Pack.BufferObj, 0, false);
1864*61046927SAndroid Build Coastguard Worker }
1865*61046927SAndroid Build Coastguard Worker if (ctx->Unpack.BufferObj == bufObj) {
1866*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->Unpack.BufferObj, 0, false);
1867*61046927SAndroid Build Coastguard Worker }
1868*61046927SAndroid Build Coastguard Worker
1869*61046927SAndroid Build Coastguard Worker if (ctx->Texture.BufferObject == bufObj) {
1870*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->Texture.BufferObject, 0, false);
1871*61046927SAndroid Build Coastguard Worker }
1872*61046927SAndroid Build Coastguard Worker
1873*61046927SAndroid Build Coastguard Worker if (ctx->ExternalVirtualMemoryBuffer == bufObj) {
1874*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->ExternalVirtualMemoryBuffer, 0, false);
1875*61046927SAndroid Build Coastguard Worker }
1876*61046927SAndroid Build Coastguard Worker
1877*61046927SAndroid Build Coastguard Worker /* unbind query buffer binding point */
1878*61046927SAndroid Build Coastguard Worker if (ctx->QueryBuffer == bufObj) {
1879*61046927SAndroid Build Coastguard Worker bind_buffer_object(ctx, &ctx->QueryBuffer, 0, false);
1880*61046927SAndroid Build Coastguard Worker }
1881*61046927SAndroid Build Coastguard Worker
1882*61046927SAndroid Build Coastguard Worker /* The ID is immediately freed for re-use */
1883*61046927SAndroid Build Coastguard Worker _mesa_HashRemoveLocked(&ctx->Shared->BufferObjects, ids[i]);
1884*61046927SAndroid Build Coastguard Worker /* Make sure we do not run into the classic ABA problem on bind.
1885*61046927SAndroid Build Coastguard Worker * We don't want to allow re-binding a buffer object that's been
1886*61046927SAndroid Build Coastguard Worker * "deleted" by glDeleteBuffers().
1887*61046927SAndroid Build Coastguard Worker *
1888*61046927SAndroid Build Coastguard Worker * The explicit rebinding to the default object in the current context
1889*61046927SAndroid Build Coastguard Worker * prevents the above in the current context, but another context
1890*61046927SAndroid Build Coastguard Worker * sharing the same objects might suffer from this problem.
1891*61046927SAndroid Build Coastguard Worker * The alternative would be to do the hash lookup in any case on bind
1892*61046927SAndroid Build Coastguard Worker * which would introduce more runtime overhead than this.
1893*61046927SAndroid Build Coastguard Worker */
1894*61046927SAndroid Build Coastguard Worker bufObj->DeletePending = GL_TRUE;
1895*61046927SAndroid Build Coastguard Worker
1896*61046927SAndroid Build Coastguard Worker /* The GLuint ID holds one reference and the context that created
1897*61046927SAndroid Build Coastguard Worker * the buffer holds the other one.
1898*61046927SAndroid Build Coastguard Worker */
1899*61046927SAndroid Build Coastguard Worker assert(p_atomic_read(&bufObj->RefCount) >= (bufObj->Ctx ? 2 : 1));
1900*61046927SAndroid Build Coastguard Worker
1901*61046927SAndroid Build Coastguard Worker if (bufObj->Ctx == ctx) {
1902*61046927SAndroid Build Coastguard Worker detach_ctx_from_buffer(ctx, bufObj);
1903*61046927SAndroid Build Coastguard Worker } else if (bufObj->Ctx) {
1904*61046927SAndroid Build Coastguard Worker /* Only the context holding it can release it. */
1905*61046927SAndroid Build Coastguard Worker _mesa_set_add(ctx->Shared->ZombieBufferObjects, bufObj);
1906*61046927SAndroid Build Coastguard Worker }
1907*61046927SAndroid Build Coastguard Worker
1908*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &bufObj, NULL);
1909*61046927SAndroid Build Coastguard Worker }
1910*61046927SAndroid Build Coastguard Worker }
1911*61046927SAndroid Build Coastguard Worker
1912*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects,
1913*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
1914*61046927SAndroid Build Coastguard Worker }
1915*61046927SAndroid Build Coastguard Worker
1916*61046927SAndroid Build Coastguard Worker
1917*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DeleteBuffers_no_error(GLsizei n,const GLuint * ids)1918*61046927SAndroid Build Coastguard Worker _mesa_DeleteBuffers_no_error(GLsizei n, const GLuint *ids)
1919*61046927SAndroid Build Coastguard Worker {
1920*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1921*61046927SAndroid Build Coastguard Worker delete_buffers(ctx, n, ids);
1922*61046927SAndroid Build Coastguard Worker }
1923*61046927SAndroid Build Coastguard Worker
1924*61046927SAndroid Build Coastguard Worker
1925*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_DeleteBuffers(GLsizei n,const GLuint * ids)1926*61046927SAndroid Build Coastguard Worker _mesa_DeleteBuffers(GLsizei n, const GLuint *ids)
1927*61046927SAndroid Build Coastguard Worker {
1928*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
1929*61046927SAndroid Build Coastguard Worker
1930*61046927SAndroid Build Coastguard Worker if (n < 0) {
1931*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteBuffersARB(n)");
1932*61046927SAndroid Build Coastguard Worker return;
1933*61046927SAndroid Build Coastguard Worker }
1934*61046927SAndroid Build Coastguard Worker
1935*61046927SAndroid Build Coastguard Worker delete_buffers(ctx, n, ids);
1936*61046927SAndroid Build Coastguard Worker }
1937*61046927SAndroid Build Coastguard Worker
1938*61046927SAndroid Build Coastguard Worker
1939*61046927SAndroid Build Coastguard Worker /**
1940*61046927SAndroid Build Coastguard Worker * This is the implementation for glGenBuffers and glCreateBuffers. It is not
1941*61046927SAndroid Build Coastguard Worker * exposed to the rest of Mesa to encourage the use of nameless buffers in
1942*61046927SAndroid Build Coastguard Worker * driver internals.
1943*61046927SAndroid Build Coastguard Worker */
1944*61046927SAndroid Build Coastguard Worker static void
create_buffers(struct gl_context * ctx,GLsizei n,GLuint * buffers,bool dsa)1945*61046927SAndroid Build Coastguard Worker create_buffers(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa)
1946*61046927SAndroid Build Coastguard Worker {
1947*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *buf;
1948*61046927SAndroid Build Coastguard Worker
1949*61046927SAndroid Build Coastguard Worker if (!buffers)
1950*61046927SAndroid Build Coastguard Worker return;
1951*61046927SAndroid Build Coastguard Worker
1952*61046927SAndroid Build Coastguard Worker /*
1953*61046927SAndroid Build Coastguard Worker * This must be atomic (generation and allocation of buffer object IDs)
1954*61046927SAndroid Build Coastguard Worker */
1955*61046927SAndroid Build Coastguard Worker _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects,
1956*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
1957*61046927SAndroid Build Coastguard Worker /* If one context only creates buffers and another context only deletes
1958*61046927SAndroid Build Coastguard Worker * buffers, buffers don't get released because it only produces zombie
1959*61046927SAndroid Build Coastguard Worker * buffers. Only the context that has created the buffers can release
1960*61046927SAndroid Build Coastguard Worker * them. Thus, when we create buffers, we prune the list of zombie
1961*61046927SAndroid Build Coastguard Worker * buffers.
1962*61046927SAndroid Build Coastguard Worker */
1963*61046927SAndroid Build Coastguard Worker unreference_zombie_buffers_for_ctx(ctx);
1964*61046927SAndroid Build Coastguard Worker
1965*61046927SAndroid Build Coastguard Worker _mesa_HashFindFreeKeys(&ctx->Shared->BufferObjects, buffers, n);
1966*61046927SAndroid Build Coastguard Worker
1967*61046927SAndroid Build Coastguard Worker /* Insert the ID and pointer into the hash table. If non-DSA, insert a
1968*61046927SAndroid Build Coastguard Worker * DummyBufferObject. Otherwise, create a new buffer object and insert
1969*61046927SAndroid Build Coastguard Worker * it.
1970*61046927SAndroid Build Coastguard Worker */
1971*61046927SAndroid Build Coastguard Worker for (int i = 0; i < n; i++) {
1972*61046927SAndroid Build Coastguard Worker if (dsa) {
1973*61046927SAndroid Build Coastguard Worker buf = new_gl_buffer_object(ctx, buffers[i]);
1974*61046927SAndroid Build Coastguard Worker if (!buf) {
1975*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCreateBuffers");
1976*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects,
1977*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
1978*61046927SAndroid Build Coastguard Worker return;
1979*61046927SAndroid Build Coastguard Worker }
1980*61046927SAndroid Build Coastguard Worker }
1981*61046927SAndroid Build Coastguard Worker else
1982*61046927SAndroid Build Coastguard Worker buf = &DummyBufferObject;
1983*61046927SAndroid Build Coastguard Worker
1984*61046927SAndroid Build Coastguard Worker _mesa_HashInsertLocked(&ctx->Shared->BufferObjects, buffers[i], buf);
1985*61046927SAndroid Build Coastguard Worker }
1986*61046927SAndroid Build Coastguard Worker
1987*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects,
1988*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
1989*61046927SAndroid Build Coastguard Worker }
1990*61046927SAndroid Build Coastguard Worker
1991*61046927SAndroid Build Coastguard Worker
1992*61046927SAndroid Build Coastguard Worker static void
create_buffers_err(struct gl_context * ctx,GLsizei n,GLuint * buffers,bool dsa)1993*61046927SAndroid Build Coastguard Worker create_buffers_err(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa)
1994*61046927SAndroid Build Coastguard Worker {
1995*61046927SAndroid Build Coastguard Worker const char *func = dsa ? "glCreateBuffers" : "glGenBuffers";
1996*61046927SAndroid Build Coastguard Worker
1997*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API)
1998*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "%s(%d)\n", func, n);
1999*61046927SAndroid Build Coastguard Worker
2000*61046927SAndroid Build Coastguard Worker if (n < 0) {
2001*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(n %d < 0)", func, n);
2002*61046927SAndroid Build Coastguard Worker return;
2003*61046927SAndroid Build Coastguard Worker }
2004*61046927SAndroid Build Coastguard Worker
2005*61046927SAndroid Build Coastguard Worker create_buffers(ctx, n, buffers, dsa);
2006*61046927SAndroid Build Coastguard Worker }
2007*61046927SAndroid Build Coastguard Worker
2008*61046927SAndroid Build Coastguard Worker /**
2009*61046927SAndroid Build Coastguard Worker * Generate a set of unique buffer object IDs and store them in \c buffers.
2010*61046927SAndroid Build Coastguard Worker *
2011*61046927SAndroid Build Coastguard Worker * \param n Number of IDs to generate.
2012*61046927SAndroid Build Coastguard Worker * \param buffers Array of \c n locations to store the IDs.
2013*61046927SAndroid Build Coastguard Worker */
2014*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GenBuffers_no_error(GLsizei n,GLuint * buffers)2015*61046927SAndroid Build Coastguard Worker _mesa_GenBuffers_no_error(GLsizei n, GLuint *buffers)
2016*61046927SAndroid Build Coastguard Worker {
2017*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2018*61046927SAndroid Build Coastguard Worker create_buffers(ctx, n, buffers, false);
2019*61046927SAndroid Build Coastguard Worker }
2020*61046927SAndroid Build Coastguard Worker
2021*61046927SAndroid Build Coastguard Worker
2022*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GenBuffers(GLsizei n,GLuint * buffers)2023*61046927SAndroid Build Coastguard Worker _mesa_GenBuffers(GLsizei n, GLuint *buffers)
2024*61046927SAndroid Build Coastguard Worker {
2025*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2026*61046927SAndroid Build Coastguard Worker create_buffers_err(ctx, n, buffers, false);
2027*61046927SAndroid Build Coastguard Worker }
2028*61046927SAndroid Build Coastguard Worker
2029*61046927SAndroid Build Coastguard Worker /**
2030*61046927SAndroid Build Coastguard Worker * Create a set of buffer objects and store their unique IDs in \c buffers.
2031*61046927SAndroid Build Coastguard Worker *
2032*61046927SAndroid Build Coastguard Worker * \param n Number of IDs to generate.
2033*61046927SAndroid Build Coastguard Worker * \param buffers Array of \c n locations to store the IDs.
2034*61046927SAndroid Build Coastguard Worker */
2035*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CreateBuffers_no_error(GLsizei n,GLuint * buffers)2036*61046927SAndroid Build Coastguard Worker _mesa_CreateBuffers_no_error(GLsizei n, GLuint *buffers)
2037*61046927SAndroid Build Coastguard Worker {
2038*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2039*61046927SAndroid Build Coastguard Worker create_buffers(ctx, n, buffers, true);
2040*61046927SAndroid Build Coastguard Worker }
2041*61046927SAndroid Build Coastguard Worker
2042*61046927SAndroid Build Coastguard Worker
2043*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CreateBuffers(GLsizei n,GLuint * buffers)2044*61046927SAndroid Build Coastguard Worker _mesa_CreateBuffers(GLsizei n, GLuint *buffers)
2045*61046927SAndroid Build Coastguard Worker {
2046*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2047*61046927SAndroid Build Coastguard Worker create_buffers_err(ctx, n, buffers, true);
2048*61046927SAndroid Build Coastguard Worker }
2049*61046927SAndroid Build Coastguard Worker
2050*61046927SAndroid Build Coastguard Worker
2051*61046927SAndroid Build Coastguard Worker /**
2052*61046927SAndroid Build Coastguard Worker * Determine if ID is the name of a buffer object.
2053*61046927SAndroid Build Coastguard Worker *
2054*61046927SAndroid Build Coastguard Worker * \param id ID of the potential buffer object.
2055*61046927SAndroid Build Coastguard Worker * \return \c GL_TRUE if \c id is the name of a buffer object,
2056*61046927SAndroid Build Coastguard Worker * \c GL_FALSE otherwise.
2057*61046927SAndroid Build Coastguard Worker */
2058*61046927SAndroid Build Coastguard Worker GLboolean GLAPIENTRY
_mesa_IsBuffer(GLuint id)2059*61046927SAndroid Build Coastguard Worker _mesa_IsBuffer(GLuint id)
2060*61046927SAndroid Build Coastguard Worker {
2061*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2062*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2063*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
2064*61046927SAndroid Build Coastguard Worker
2065*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, id);
2066*61046927SAndroid Build Coastguard Worker
2067*61046927SAndroid Build Coastguard Worker return bufObj && bufObj != &DummyBufferObject;
2068*61046927SAndroid Build Coastguard Worker }
2069*61046927SAndroid Build Coastguard Worker
2070*61046927SAndroid Build Coastguard Worker
2071*61046927SAndroid Build Coastguard Worker static bool
validate_buffer_storage(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLsizeiptr size,GLbitfield flags,const char * func)2072*61046927SAndroid Build Coastguard Worker validate_buffer_storage(struct gl_context *ctx,
2073*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj, GLsizeiptr size,
2074*61046927SAndroid Build Coastguard Worker GLbitfield flags, const char *func)
2075*61046927SAndroid Build Coastguard Worker {
2076*61046927SAndroid Build Coastguard Worker if (size <= 0) {
2077*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(size <= 0)", func);
2078*61046927SAndroid Build Coastguard Worker return false;
2079*61046927SAndroid Build Coastguard Worker }
2080*61046927SAndroid Build Coastguard Worker
2081*61046927SAndroid Build Coastguard Worker GLbitfield valid_flags = GL_MAP_READ_BIT |
2082*61046927SAndroid Build Coastguard Worker GL_MAP_WRITE_BIT |
2083*61046927SAndroid Build Coastguard Worker GL_MAP_PERSISTENT_BIT |
2084*61046927SAndroid Build Coastguard Worker GL_MAP_COHERENT_BIT |
2085*61046927SAndroid Build Coastguard Worker GL_DYNAMIC_STORAGE_BIT |
2086*61046927SAndroid Build Coastguard Worker GL_CLIENT_STORAGE_BIT;
2087*61046927SAndroid Build Coastguard Worker
2088*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.ARB_sparse_buffer)
2089*61046927SAndroid Build Coastguard Worker valid_flags |= GL_SPARSE_STORAGE_BIT_ARB;
2090*61046927SAndroid Build Coastguard Worker
2091*61046927SAndroid Build Coastguard Worker if (flags & ~valid_flags) {
2092*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(invalid flag bits set)", func);
2093*61046927SAndroid Build Coastguard Worker return false;
2094*61046927SAndroid Build Coastguard Worker }
2095*61046927SAndroid Build Coastguard Worker
2096*61046927SAndroid Build Coastguard Worker /* The Errors section of the GL_ARB_sparse_buffer spec says:
2097*61046927SAndroid Build Coastguard Worker *
2098*61046927SAndroid Build Coastguard Worker * "INVALID_VALUE is generated by BufferStorage if <flags> contains
2099*61046927SAndroid Build Coastguard Worker * SPARSE_STORAGE_BIT_ARB and <flags> also contains any combination of
2100*61046927SAndroid Build Coastguard Worker * MAP_READ_BIT or MAP_WRITE_BIT."
2101*61046927SAndroid Build Coastguard Worker */
2102*61046927SAndroid Build Coastguard Worker if (flags & GL_SPARSE_STORAGE_BIT_ARB &&
2103*61046927SAndroid Build Coastguard Worker flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) {
2104*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(SPARSE_STORAGE and READ/WRITE)", func);
2105*61046927SAndroid Build Coastguard Worker return false;
2106*61046927SAndroid Build Coastguard Worker }
2107*61046927SAndroid Build Coastguard Worker
2108*61046927SAndroid Build Coastguard Worker if (flags & GL_MAP_PERSISTENT_BIT &&
2109*61046927SAndroid Build Coastguard Worker !(flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))) {
2110*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
2111*61046927SAndroid Build Coastguard Worker "%s(PERSISTENT and flags!=READ/WRITE)", func);
2112*61046927SAndroid Build Coastguard Worker return false;
2113*61046927SAndroid Build Coastguard Worker }
2114*61046927SAndroid Build Coastguard Worker
2115*61046927SAndroid Build Coastguard Worker if (flags & GL_MAP_COHERENT_BIT && !(flags & GL_MAP_PERSISTENT_BIT)) {
2116*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
2117*61046927SAndroid Build Coastguard Worker "%s(COHERENT and flags!=PERSISTENT)", func);
2118*61046927SAndroid Build Coastguard Worker return false;
2119*61046927SAndroid Build Coastguard Worker }
2120*61046927SAndroid Build Coastguard Worker
2121*61046927SAndroid Build Coastguard Worker if (bufObj->Immutable || bufObj->HandleAllocated) {
2122*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func);
2123*61046927SAndroid Build Coastguard Worker return false;
2124*61046927SAndroid Build Coastguard Worker }
2125*61046927SAndroid Build Coastguard Worker
2126*61046927SAndroid Build Coastguard Worker return true;
2127*61046927SAndroid Build Coastguard Worker }
2128*61046927SAndroid Build Coastguard Worker
2129*61046927SAndroid Build Coastguard Worker
2130*61046927SAndroid Build Coastguard Worker static void
buffer_storage(struct gl_context * ctx,struct gl_buffer_object * bufObj,struct gl_memory_object * memObj,GLenum target,GLsizeiptr size,const GLvoid * data,GLbitfield flags,GLuint64 offset,const char * func)2131*61046927SAndroid Build Coastguard Worker buffer_storage(struct gl_context *ctx, struct gl_buffer_object *bufObj,
2132*61046927SAndroid Build Coastguard Worker struct gl_memory_object *memObj, GLenum target,
2133*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid *data, GLbitfield flags,
2134*61046927SAndroid Build Coastguard Worker GLuint64 offset, const char *func)
2135*61046927SAndroid Build Coastguard Worker {
2136*61046927SAndroid Build Coastguard Worker GLboolean res;
2137*61046927SAndroid Build Coastguard Worker
2138*61046927SAndroid Build Coastguard Worker /* Unmap the existing buffer. We'll replace it now. Not an error. */
2139*61046927SAndroid Build Coastguard Worker _mesa_buffer_unmap_all_mappings(ctx, bufObj);
2140*61046927SAndroid Build Coastguard Worker
2141*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
2142*61046927SAndroid Build Coastguard Worker
2143*61046927SAndroid Build Coastguard Worker bufObj->Immutable = GL_TRUE;
2144*61046927SAndroid Build Coastguard Worker bufObj->MinMaxCacheDirty = true;
2145*61046927SAndroid Build Coastguard Worker
2146*61046927SAndroid Build Coastguard Worker if (memObj) {
2147*61046927SAndroid Build Coastguard Worker res = bufferobj_data_mem(ctx, target, size, memObj, offset,
2148*61046927SAndroid Build Coastguard Worker GL_DYNAMIC_DRAW, bufObj);
2149*61046927SAndroid Build Coastguard Worker }
2150*61046927SAndroid Build Coastguard Worker else {
2151*61046927SAndroid Build Coastguard Worker res = _mesa_bufferobj_data(ctx, target, size, data, GL_DYNAMIC_DRAW,
2152*61046927SAndroid Build Coastguard Worker flags, bufObj);
2153*61046927SAndroid Build Coastguard Worker }
2154*61046927SAndroid Build Coastguard Worker
2155*61046927SAndroid Build Coastguard Worker if (!res) {
2156*61046927SAndroid Build Coastguard Worker if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
2157*61046927SAndroid Build Coastguard Worker /* Even though the interaction between AMD_pinned_memory and
2158*61046927SAndroid Build Coastguard Worker * glBufferStorage is not described in the spec, Graham Sellers
2159*61046927SAndroid Build Coastguard Worker * said that it should behave the same as glBufferData.
2160*61046927SAndroid Build Coastguard Worker */
2161*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
2162*61046927SAndroid Build Coastguard Worker }
2163*61046927SAndroid Build Coastguard Worker else {
2164*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
2165*61046927SAndroid Build Coastguard Worker }
2166*61046927SAndroid Build Coastguard Worker }
2167*61046927SAndroid Build Coastguard Worker }
2168*61046927SAndroid Build Coastguard Worker
2169*61046927SAndroid Build Coastguard Worker
2170*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
inlined_buffer_storage(GLenum target,GLuint buffer,GLsizeiptr size,const GLvoid * data,GLbitfield flags,GLuint memory,GLuint64 offset,bool dsa,bool mem,bool no_error,const char * func)2171*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(GLenum target, GLuint buffer, GLsizeiptr size,
2172*61046927SAndroid Build Coastguard Worker const GLvoid *data, GLbitfield flags,
2173*61046927SAndroid Build Coastguard Worker GLuint memory, GLuint64 offset,
2174*61046927SAndroid Build Coastguard Worker bool dsa, bool mem, bool no_error, const char *func)
2175*61046927SAndroid Build Coastguard Worker {
2176*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2177*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2178*61046927SAndroid Build Coastguard Worker struct gl_memory_object *memObj = NULL;
2179*61046927SAndroid Build Coastguard Worker
2180*61046927SAndroid Build Coastguard Worker if (mem) {
2181*61046927SAndroid Build Coastguard Worker if (!no_error) {
2182*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.EXT_memory_object) {
2183*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
2184*61046927SAndroid Build Coastguard Worker return;
2185*61046927SAndroid Build Coastguard Worker }
2186*61046927SAndroid Build Coastguard Worker
2187*61046927SAndroid Build Coastguard Worker /* From the EXT_external_objects spec:
2188*61046927SAndroid Build Coastguard Worker *
2189*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated by BufferStorageMemEXT and
2190*61046927SAndroid Build Coastguard Worker * NamedBufferStorageMemEXT if <memory> is 0, or ..."
2191*61046927SAndroid Build Coastguard Worker */
2192*61046927SAndroid Build Coastguard Worker if (memory == 0) {
2193*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory == 0)", func);
2194*61046927SAndroid Build Coastguard Worker }
2195*61046927SAndroid Build Coastguard Worker }
2196*61046927SAndroid Build Coastguard Worker
2197*61046927SAndroid Build Coastguard Worker memObj = _mesa_lookup_memory_object(ctx, memory);
2198*61046927SAndroid Build Coastguard Worker if (!memObj)
2199*61046927SAndroid Build Coastguard Worker return;
2200*61046927SAndroid Build Coastguard Worker
2201*61046927SAndroid Build Coastguard Worker /* From the EXT_external_objects spec:
2202*61046927SAndroid Build Coastguard Worker *
2203*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if <memory> names a
2204*61046927SAndroid Build Coastguard Worker * valid memory object which has no associated memory."
2205*61046927SAndroid Build Coastguard Worker */
2206*61046927SAndroid Build Coastguard Worker if (!no_error && !memObj->Immutable) {
2207*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
2208*61046927SAndroid Build Coastguard Worker func);
2209*61046927SAndroid Build Coastguard Worker return;
2210*61046927SAndroid Build Coastguard Worker }
2211*61046927SAndroid Build Coastguard Worker }
2212*61046927SAndroid Build Coastguard Worker
2213*61046927SAndroid Build Coastguard Worker if (dsa) {
2214*61046927SAndroid Build Coastguard Worker if (no_error) {
2215*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2216*61046927SAndroid Build Coastguard Worker } else {
2217*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, func);
2218*61046927SAndroid Build Coastguard Worker if (!bufObj)
2219*61046927SAndroid Build Coastguard Worker return;
2220*61046927SAndroid Build Coastguard Worker }
2221*61046927SAndroid Build Coastguard Worker } else {
2222*61046927SAndroid Build Coastguard Worker if (no_error) {
2223*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObjPtr =
2224*61046927SAndroid Build Coastguard Worker get_buffer_target(ctx, target, true);
2225*61046927SAndroid Build Coastguard Worker bufObj = *bufObjPtr;
2226*61046927SAndroid Build Coastguard Worker } else {
2227*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, func, target, GL_INVALID_OPERATION);
2228*61046927SAndroid Build Coastguard Worker if (!bufObj)
2229*61046927SAndroid Build Coastguard Worker return;
2230*61046927SAndroid Build Coastguard Worker }
2231*61046927SAndroid Build Coastguard Worker }
2232*61046927SAndroid Build Coastguard Worker
2233*61046927SAndroid Build Coastguard Worker if (no_error || validate_buffer_storage(ctx, bufObj, size, flags, func))
2234*61046927SAndroid Build Coastguard Worker buffer_storage(ctx, bufObj, memObj, target, size, data, flags, offset, func);
2235*61046927SAndroid Build Coastguard Worker }
2236*61046927SAndroid Build Coastguard Worker
2237*61046927SAndroid Build Coastguard Worker
2238*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BufferStorage_no_error(GLenum target,GLsizeiptr size,const GLvoid * data,GLbitfield flags)2239*61046927SAndroid Build Coastguard Worker _mesa_BufferStorage_no_error(GLenum target, GLsizeiptr size,
2240*61046927SAndroid Build Coastguard Worker const GLvoid *data, GLbitfield flags)
2241*61046927SAndroid Build Coastguard Worker {
2242*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(target, 0, size, data, flags, GL_NONE, 0,
2243*61046927SAndroid Build Coastguard Worker false, false, true, "glBufferStorage");
2244*61046927SAndroid Build Coastguard Worker }
2245*61046927SAndroid Build Coastguard Worker
2246*61046927SAndroid Build Coastguard Worker
2247*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BufferStorage(GLenum target,GLsizeiptr size,const GLvoid * data,GLbitfield flags)2248*61046927SAndroid Build Coastguard Worker _mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data,
2249*61046927SAndroid Build Coastguard Worker GLbitfield flags)
2250*61046927SAndroid Build Coastguard Worker {
2251*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(target, 0, size, data, flags, GL_NONE, 0,
2252*61046927SAndroid Build Coastguard Worker false, false, false, "glBufferStorage");
2253*61046927SAndroid Build Coastguard Worker }
2254*61046927SAndroid Build Coastguard Worker
2255*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferStorageEXT(GLuint buffer,GLsizeiptr size,const GLvoid * data,GLbitfield flags)2256*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferStorageEXT(GLuint buffer, GLsizeiptr size,
2257*61046927SAndroid Build Coastguard Worker const GLvoid *data, GLbitfield flags)
2258*61046927SAndroid Build Coastguard Worker {
2259*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2260*61046927SAndroid Build Coastguard Worker
2261*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2262*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
2263*61046927SAndroid Build Coastguard Worker &bufObj, "glNamedBufferStorageEXT", false))
2264*61046927SAndroid Build Coastguard Worker return;
2265*61046927SAndroid Build Coastguard Worker
2266*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(GL_NONE, buffer, size, data, flags, GL_NONE, 0,
2267*61046927SAndroid Build Coastguard Worker true, false, false, "glNamedBufferStorageEXT");
2268*61046927SAndroid Build Coastguard Worker }
2269*61046927SAndroid Build Coastguard Worker
2270*61046927SAndroid Build Coastguard Worker
2271*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BufferStorageMemEXT(GLenum target,GLsizeiptr size,GLuint memory,GLuint64 offset)2272*61046927SAndroid Build Coastguard Worker _mesa_BufferStorageMemEXT(GLenum target, GLsizeiptr size,
2273*61046927SAndroid Build Coastguard Worker GLuint memory, GLuint64 offset)
2274*61046927SAndroid Build Coastguard Worker {
2275*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(target, 0, size, NULL, 0, memory, offset,
2276*61046927SAndroid Build Coastguard Worker false, true, false, "glBufferStorageMemEXT");
2277*61046927SAndroid Build Coastguard Worker }
2278*61046927SAndroid Build Coastguard Worker
2279*61046927SAndroid Build Coastguard Worker
2280*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BufferStorageMemEXT_no_error(GLenum target,GLsizeiptr size,GLuint memory,GLuint64 offset)2281*61046927SAndroid Build Coastguard Worker _mesa_BufferStorageMemEXT_no_error(GLenum target, GLsizeiptr size,
2282*61046927SAndroid Build Coastguard Worker GLuint memory, GLuint64 offset)
2283*61046927SAndroid Build Coastguard Worker {
2284*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(target, 0, size, NULL, 0, memory, offset,
2285*61046927SAndroid Build Coastguard Worker false, true, true, "glBufferStorageMemEXT");
2286*61046927SAndroid Build Coastguard Worker }
2287*61046927SAndroid Build Coastguard Worker
2288*61046927SAndroid Build Coastguard Worker
2289*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferStorage_no_error(GLuint buffer,GLsizeiptr size,const GLvoid * data,GLbitfield flags)2290*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferStorage_no_error(GLuint buffer, GLsizeiptr size,
2291*61046927SAndroid Build Coastguard Worker const GLvoid *data, GLbitfield flags)
2292*61046927SAndroid Build Coastguard Worker {
2293*61046927SAndroid Build Coastguard Worker /* In direct state access, buffer objects have an unspecified target
2294*61046927SAndroid Build Coastguard Worker * since they are not required to be bound.
2295*61046927SAndroid Build Coastguard Worker */
2296*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(GL_NONE, buffer, size, data, flags, GL_NONE, 0,
2297*61046927SAndroid Build Coastguard Worker true, false, true, "glNamedBufferStorage");
2298*61046927SAndroid Build Coastguard Worker }
2299*61046927SAndroid Build Coastguard Worker
2300*61046927SAndroid Build Coastguard Worker
2301*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferStorage(GLuint buffer,GLsizeiptr size,const GLvoid * data,GLbitfield flags)2302*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferStorage(GLuint buffer, GLsizeiptr size, const GLvoid *data,
2303*61046927SAndroid Build Coastguard Worker GLbitfield flags)
2304*61046927SAndroid Build Coastguard Worker {
2305*61046927SAndroid Build Coastguard Worker /* In direct state access, buffer objects have an unspecified target
2306*61046927SAndroid Build Coastguard Worker * since they are not required to be bound.
2307*61046927SAndroid Build Coastguard Worker */
2308*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(GL_NONE, buffer, size, data, flags, GL_NONE, 0,
2309*61046927SAndroid Build Coastguard Worker true, false, false, "glNamedBufferStorage");
2310*61046927SAndroid Build Coastguard Worker }
2311*61046927SAndroid Build Coastguard Worker
2312*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferStorageMemEXT(GLuint buffer,GLsizeiptr size,GLuint memory,GLuint64 offset)2313*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferStorageMemEXT(GLuint buffer, GLsizeiptr size,
2314*61046927SAndroid Build Coastguard Worker GLuint memory, GLuint64 offset)
2315*61046927SAndroid Build Coastguard Worker {
2316*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(GL_NONE, buffer, size, NULL, 0, memory, offset,
2317*61046927SAndroid Build Coastguard Worker true, true, false, "glNamedBufferStorageMemEXT");
2318*61046927SAndroid Build Coastguard Worker }
2319*61046927SAndroid Build Coastguard Worker
2320*61046927SAndroid Build Coastguard Worker
2321*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferStorageMemEXT_no_error(GLuint buffer,GLsizeiptr size,GLuint memory,GLuint64 offset)2322*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferStorageMemEXT_no_error(GLuint buffer, GLsizeiptr size,
2323*61046927SAndroid Build Coastguard Worker GLuint memory, GLuint64 offset)
2324*61046927SAndroid Build Coastguard Worker {
2325*61046927SAndroid Build Coastguard Worker inlined_buffer_storage(GL_NONE, buffer, size, NULL, 0, memory, offset,
2326*61046927SAndroid Build Coastguard Worker true, true, true, "glNamedBufferStorageMemEXT");
2327*61046927SAndroid Build Coastguard Worker }
2328*61046927SAndroid Build Coastguard Worker
2329*61046927SAndroid Build Coastguard Worker
2330*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
buffer_data(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage,const char * func,bool no_error)2331*61046927SAndroid Build Coastguard Worker buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
2332*61046927SAndroid Build Coastguard Worker GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage,
2333*61046927SAndroid Build Coastguard Worker const char *func, bool no_error)
2334*61046927SAndroid Build Coastguard Worker {
2335*61046927SAndroid Build Coastguard Worker bool valid_usage;
2336*61046927SAndroid Build Coastguard Worker
2337*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API) {
2338*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "%s(%s, %ld, %p, %s)\n",
2339*61046927SAndroid Build Coastguard Worker func,
2340*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target),
2341*61046927SAndroid Build Coastguard Worker (long int) size, data,
2342*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(usage));
2343*61046927SAndroid Build Coastguard Worker }
2344*61046927SAndroid Build Coastguard Worker
2345*61046927SAndroid Build Coastguard Worker if (!no_error) {
2346*61046927SAndroid Build Coastguard Worker if (size < 0) {
2347*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(size < 0)", func);
2348*61046927SAndroid Build Coastguard Worker return;
2349*61046927SAndroid Build Coastguard Worker }
2350*61046927SAndroid Build Coastguard Worker
2351*61046927SAndroid Build Coastguard Worker switch (usage) {
2352*61046927SAndroid Build Coastguard Worker case GL_STREAM_DRAW_ARB:
2353*61046927SAndroid Build Coastguard Worker valid_usage = (ctx->API != API_OPENGLES);
2354*61046927SAndroid Build Coastguard Worker break;
2355*61046927SAndroid Build Coastguard Worker case GL_STATIC_DRAW_ARB:
2356*61046927SAndroid Build Coastguard Worker case GL_DYNAMIC_DRAW_ARB:
2357*61046927SAndroid Build Coastguard Worker valid_usage = true;
2358*61046927SAndroid Build Coastguard Worker break;
2359*61046927SAndroid Build Coastguard Worker case GL_STREAM_READ_ARB:
2360*61046927SAndroid Build Coastguard Worker case GL_STREAM_COPY_ARB:
2361*61046927SAndroid Build Coastguard Worker case GL_STATIC_READ_ARB:
2362*61046927SAndroid Build Coastguard Worker case GL_STATIC_COPY_ARB:
2363*61046927SAndroid Build Coastguard Worker case GL_DYNAMIC_READ_ARB:
2364*61046927SAndroid Build Coastguard Worker case GL_DYNAMIC_COPY_ARB:
2365*61046927SAndroid Build Coastguard Worker valid_usage = _mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx);
2366*61046927SAndroid Build Coastguard Worker break;
2367*61046927SAndroid Build Coastguard Worker default:
2368*61046927SAndroid Build Coastguard Worker valid_usage = false;
2369*61046927SAndroid Build Coastguard Worker break;
2370*61046927SAndroid Build Coastguard Worker }
2371*61046927SAndroid Build Coastguard Worker
2372*61046927SAndroid Build Coastguard Worker if (!valid_usage) {
2373*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid usage: %s)", func,
2374*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(usage));
2375*61046927SAndroid Build Coastguard Worker return;
2376*61046927SAndroid Build Coastguard Worker }
2377*61046927SAndroid Build Coastguard Worker
2378*61046927SAndroid Build Coastguard Worker if (bufObj->Immutable || bufObj->HandleAllocated) {
2379*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable)", func);
2380*61046927SAndroid Build Coastguard Worker return;
2381*61046927SAndroid Build Coastguard Worker }
2382*61046927SAndroid Build Coastguard Worker }
2383*61046927SAndroid Build Coastguard Worker
2384*61046927SAndroid Build Coastguard Worker /* Unmap the existing buffer. We'll replace it now. Not an error. */
2385*61046927SAndroid Build Coastguard Worker _mesa_buffer_unmap_all_mappings(ctx, bufObj);
2386*61046927SAndroid Build Coastguard Worker
2387*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
2388*61046927SAndroid Build Coastguard Worker
2389*61046927SAndroid Build Coastguard Worker bufObj->MinMaxCacheDirty = true;
2390*61046927SAndroid Build Coastguard Worker
2391*61046927SAndroid Build Coastguard Worker #ifdef VBO_DEBUG
2392*61046927SAndroid Build Coastguard Worker printf("glBufferDataARB(%u, sz %ld, from %p, usage 0x%x)\n",
2393*61046927SAndroid Build Coastguard Worker bufObj->Name, size, data, usage);
2394*61046927SAndroid Build Coastguard Worker #endif
2395*61046927SAndroid Build Coastguard Worker
2396*61046927SAndroid Build Coastguard Worker #ifdef BOUNDS_CHECK
2397*61046927SAndroid Build Coastguard Worker size += 100;
2398*61046927SAndroid Build Coastguard Worker #endif
2399*61046927SAndroid Build Coastguard Worker
2400*61046927SAndroid Build Coastguard Worker if (!_mesa_bufferobj_data(ctx, target, size, data, usage,
2401*61046927SAndroid Build Coastguard Worker GL_MAP_READ_BIT |
2402*61046927SAndroid Build Coastguard Worker GL_MAP_WRITE_BIT |
2403*61046927SAndroid Build Coastguard Worker GL_DYNAMIC_STORAGE_BIT,
2404*61046927SAndroid Build Coastguard Worker bufObj)) {
2405*61046927SAndroid Build Coastguard Worker if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) {
2406*61046927SAndroid Build Coastguard Worker if (!no_error) {
2407*61046927SAndroid Build Coastguard Worker /* From GL_AMD_pinned_memory:
2408*61046927SAndroid Build Coastguard Worker *
2409*61046927SAndroid Build Coastguard Worker * INVALID_OPERATION is generated by BufferData if <target> is
2410*61046927SAndroid Build Coastguard Worker * EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, and the store cannot be
2411*61046927SAndroid Build Coastguard Worker * mapped to the GPU address space.
2412*61046927SAndroid Build Coastguard Worker */
2413*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
2414*61046927SAndroid Build Coastguard Worker }
2415*61046927SAndroid Build Coastguard Worker } else {
2416*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
2417*61046927SAndroid Build Coastguard Worker }
2418*61046927SAndroid Build Coastguard Worker }
2419*61046927SAndroid Build Coastguard Worker }
2420*61046927SAndroid Build Coastguard Worker
2421*61046927SAndroid Build Coastguard Worker static void
buffer_data_error(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage,const char * func)2422*61046927SAndroid Build Coastguard Worker buffer_data_error(struct gl_context *ctx, struct gl_buffer_object *bufObj,
2423*61046927SAndroid Build Coastguard Worker GLenum target, GLsizeiptr size, const GLvoid *data,
2424*61046927SAndroid Build Coastguard Worker GLenum usage, const char *func)
2425*61046927SAndroid Build Coastguard Worker {
2426*61046927SAndroid Build Coastguard Worker buffer_data(ctx, bufObj, target, size, data, usage, func, false);
2427*61046927SAndroid Build Coastguard Worker }
2428*61046927SAndroid Build Coastguard Worker
2429*61046927SAndroid Build Coastguard Worker static void
buffer_data_no_error(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage,const char * func)2430*61046927SAndroid Build Coastguard Worker buffer_data_no_error(struct gl_context *ctx, struct gl_buffer_object *bufObj,
2431*61046927SAndroid Build Coastguard Worker GLenum target, GLsizeiptr size, const GLvoid *data,
2432*61046927SAndroid Build Coastguard Worker GLenum usage, const char *func)
2433*61046927SAndroid Build Coastguard Worker {
2434*61046927SAndroid Build Coastguard Worker buffer_data(ctx, bufObj, target, size, data, usage, func, true);
2435*61046927SAndroid Build Coastguard Worker }
2436*61046927SAndroid Build Coastguard Worker
2437*61046927SAndroid Build Coastguard Worker void
_mesa_buffer_data(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage,const char * func)2438*61046927SAndroid Build Coastguard Worker _mesa_buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
2439*61046927SAndroid Build Coastguard Worker GLenum target, GLsizeiptr size, const GLvoid *data,
2440*61046927SAndroid Build Coastguard Worker GLenum usage, const char *func)
2441*61046927SAndroid Build Coastguard Worker {
2442*61046927SAndroid Build Coastguard Worker buffer_data_error(ctx, bufObj, target, size, data, usage, func);
2443*61046927SAndroid Build Coastguard Worker }
2444*61046927SAndroid Build Coastguard Worker
2445*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BufferData_no_error(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)2446*61046927SAndroid Build Coastguard Worker _mesa_BufferData_no_error(GLenum target, GLsizeiptr size, const GLvoid *data,
2447*61046927SAndroid Build Coastguard Worker GLenum usage)
2448*61046927SAndroid Build Coastguard Worker {
2449*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2450*61046927SAndroid Build Coastguard Worker
2451*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObj = get_buffer_target(ctx, target, true);
2452*61046927SAndroid Build Coastguard Worker buffer_data_no_error(ctx, *bufObj, target, size, data, usage,
2453*61046927SAndroid Build Coastguard Worker "glBufferData");
2454*61046927SAndroid Build Coastguard Worker }
2455*61046927SAndroid Build Coastguard Worker
2456*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)2457*61046927SAndroid Build Coastguard Worker _mesa_BufferData(GLenum target, GLsizeiptr size,
2458*61046927SAndroid Build Coastguard Worker const GLvoid *data, GLenum usage)
2459*61046927SAndroid Build Coastguard Worker {
2460*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2461*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2462*61046927SAndroid Build Coastguard Worker
2463*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glBufferData", target, GL_INVALID_OPERATION);
2464*61046927SAndroid Build Coastguard Worker if (!bufObj)
2465*61046927SAndroid Build Coastguard Worker return;
2466*61046927SAndroid Build Coastguard Worker
2467*61046927SAndroid Build Coastguard Worker _mesa_buffer_data(ctx, bufObj, target, size, data, usage,
2468*61046927SAndroid Build Coastguard Worker "glBufferData");
2469*61046927SAndroid Build Coastguard Worker }
2470*61046927SAndroid Build Coastguard Worker
2471*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferData_no_error(GLuint buffer,GLsizeiptr size,const GLvoid * data,GLenum usage)2472*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferData_no_error(GLuint buffer, GLsizeiptr size,
2473*61046927SAndroid Build Coastguard Worker const GLvoid *data, GLenum usage)
2474*61046927SAndroid Build Coastguard Worker {
2475*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2476*61046927SAndroid Build Coastguard Worker
2477*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2478*61046927SAndroid Build Coastguard Worker buffer_data_no_error(ctx, bufObj, GL_NONE, size, data, usage,
2479*61046927SAndroid Build Coastguard Worker "glNamedBufferData");
2480*61046927SAndroid Build Coastguard Worker }
2481*61046927SAndroid Build Coastguard Worker
2482*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferData(GLuint buffer,GLsizeiptr size,const GLvoid * data,GLenum usage)2483*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferData(GLuint buffer, GLsizeiptr size, const GLvoid *data,
2484*61046927SAndroid Build Coastguard Worker GLenum usage)
2485*61046927SAndroid Build Coastguard Worker {
2486*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2487*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2488*61046927SAndroid Build Coastguard Worker
2489*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glNamedBufferData");
2490*61046927SAndroid Build Coastguard Worker if (!bufObj)
2491*61046927SAndroid Build Coastguard Worker return;
2492*61046927SAndroid Build Coastguard Worker
2493*61046927SAndroid Build Coastguard Worker /* In direct state access, buffer objects have an unspecified target since
2494*61046927SAndroid Build Coastguard Worker * they are not required to be bound.
2495*61046927SAndroid Build Coastguard Worker */
2496*61046927SAndroid Build Coastguard Worker _mesa_buffer_data(ctx, bufObj, GL_NONE, size, data, usage,
2497*61046927SAndroid Build Coastguard Worker "glNamedBufferData");
2498*61046927SAndroid Build Coastguard Worker }
2499*61046927SAndroid Build Coastguard Worker
2500*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferDataEXT(GLuint buffer,GLsizeiptr size,const GLvoid * data,GLenum usage)2501*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const GLvoid *data,
2502*61046927SAndroid Build Coastguard Worker GLenum usage)
2503*61046927SAndroid Build Coastguard Worker {
2504*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2505*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2506*61046927SAndroid Build Coastguard Worker
2507*61046927SAndroid Build Coastguard Worker if (!buffer) {
2508*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
2509*61046927SAndroid Build Coastguard Worker "glNamedBufferDataEXT(buffer=0)");
2510*61046927SAndroid Build Coastguard Worker return;
2511*61046927SAndroid Build Coastguard Worker }
2512*61046927SAndroid Build Coastguard Worker
2513*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2514*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
2515*61046927SAndroid Build Coastguard Worker &bufObj, "glNamedBufferDataEXT", false))
2516*61046927SAndroid Build Coastguard Worker return;
2517*61046927SAndroid Build Coastguard Worker
2518*61046927SAndroid Build Coastguard Worker _mesa_buffer_data(ctx, bufObj, GL_NONE, size, data, usage,
2519*61046927SAndroid Build Coastguard Worker "glNamedBufferDataEXT");
2520*61046927SAndroid Build Coastguard Worker }
2521*61046927SAndroid Build Coastguard Worker
2522*61046927SAndroid Build Coastguard Worker static bool
validate_buffer_sub_data(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,const char * func)2523*61046927SAndroid Build Coastguard Worker validate_buffer_sub_data(struct gl_context *ctx,
2524*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
2525*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size,
2526*61046927SAndroid Build Coastguard Worker const char *func)
2527*61046927SAndroid Build Coastguard Worker {
2528*61046927SAndroid Build Coastguard Worker if (!buffer_object_subdata_range_good(ctx, bufObj, offset, size,
2529*61046927SAndroid Build Coastguard Worker true, func)) {
2530*61046927SAndroid Build Coastguard Worker /* error already recorded */
2531*61046927SAndroid Build Coastguard Worker return false;
2532*61046927SAndroid Build Coastguard Worker }
2533*61046927SAndroid Build Coastguard Worker
2534*61046927SAndroid Build Coastguard Worker if (bufObj->Immutable &&
2535*61046927SAndroid Build Coastguard Worker !(bufObj->StorageFlags & GL_DYNAMIC_STORAGE_BIT)) {
2536*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s", func);
2537*61046927SAndroid Build Coastguard Worker return false;
2538*61046927SAndroid Build Coastguard Worker }
2539*61046927SAndroid Build Coastguard Worker
2540*61046927SAndroid Build Coastguard Worker if ((bufObj->Usage == GL_STATIC_DRAW ||
2541*61046927SAndroid Build Coastguard Worker bufObj->Usage == GL_STATIC_COPY) &&
2542*61046927SAndroid Build Coastguard Worker bufObj->NumSubDataCalls >= BUFFER_WARNING_CALL_COUNT - 1) {
2543*61046927SAndroid Build Coastguard Worker /* If the application declared the buffer as static draw/copy or stream
2544*61046927SAndroid Build Coastguard Worker * draw, it should not be frequently modified with glBufferSubData.
2545*61046927SAndroid Build Coastguard Worker */
2546*61046927SAndroid Build Coastguard Worker BUFFER_USAGE_WARNING(ctx,
2547*61046927SAndroid Build Coastguard Worker "using %s(buffer %u, offset %u, size %u) to "
2548*61046927SAndroid Build Coastguard Worker "update a %s buffer",
2549*61046927SAndroid Build Coastguard Worker func, bufObj->Name, offset, size,
2550*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(bufObj->Usage));
2551*61046927SAndroid Build Coastguard Worker }
2552*61046927SAndroid Build Coastguard Worker
2553*61046927SAndroid Build Coastguard Worker return true;
2554*61046927SAndroid Build Coastguard Worker }
2555*61046927SAndroid Build Coastguard Worker
2556*61046927SAndroid Build Coastguard Worker
2557*61046927SAndroid Build Coastguard Worker /**
2558*61046927SAndroid Build Coastguard Worker * Implementation for glBufferSubData and glNamedBufferSubData.
2559*61046927SAndroid Build Coastguard Worker *
2560*61046927SAndroid Build Coastguard Worker * \param ctx GL context.
2561*61046927SAndroid Build Coastguard Worker * \param bufObj The buffer object.
2562*61046927SAndroid Build Coastguard Worker * \param offset Offset of the first byte of the subdata range.
2563*61046927SAndroid Build Coastguard Worker * \param size Size, in bytes, of the subdata range.
2564*61046927SAndroid Build Coastguard Worker * \param data The data store.
2565*61046927SAndroid Build Coastguard Worker * \param func Name of calling function for recording errors.
2566*61046927SAndroid Build Coastguard Worker *
2567*61046927SAndroid Build Coastguard Worker */
2568*61046927SAndroid Build Coastguard Worker void
_mesa_buffer_sub_data(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size,const GLvoid * data)2569*61046927SAndroid Build Coastguard Worker _mesa_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
2570*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size, const GLvoid *data)
2571*61046927SAndroid Build Coastguard Worker {
2572*61046927SAndroid Build Coastguard Worker if (size == 0)
2573*61046927SAndroid Build Coastguard Worker return;
2574*61046927SAndroid Build Coastguard Worker
2575*61046927SAndroid Build Coastguard Worker bufObj->NumSubDataCalls++;
2576*61046927SAndroid Build Coastguard Worker bufObj->MinMaxCacheDirty = true;
2577*61046927SAndroid Build Coastguard Worker
2578*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_subdata(ctx, offset, size, data, bufObj);
2579*61046927SAndroid Build Coastguard Worker }
2580*61046927SAndroid Build Coastguard Worker
2581*61046927SAndroid Build Coastguard Worker
2582*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
buffer_sub_data(GLenum target,GLuint buffer,GLintptr offset,GLsizeiptr size,const GLvoid * data,bool dsa,bool no_error,const char * func)2583*61046927SAndroid Build Coastguard Worker buffer_sub_data(GLenum target, GLuint buffer, GLintptr offset,
2584*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid *data,
2585*61046927SAndroid Build Coastguard Worker bool dsa, bool no_error, const char *func)
2586*61046927SAndroid Build Coastguard Worker {
2587*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2588*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2589*61046927SAndroid Build Coastguard Worker
2590*61046927SAndroid Build Coastguard Worker if (dsa) {
2591*61046927SAndroid Build Coastguard Worker if (no_error) {
2592*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2593*61046927SAndroid Build Coastguard Worker } else {
2594*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, func);
2595*61046927SAndroid Build Coastguard Worker if (!bufObj)
2596*61046927SAndroid Build Coastguard Worker return;
2597*61046927SAndroid Build Coastguard Worker }
2598*61046927SAndroid Build Coastguard Worker } else {
2599*61046927SAndroid Build Coastguard Worker if (no_error) {
2600*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true);
2601*61046927SAndroid Build Coastguard Worker bufObj = *bufObjPtr;
2602*61046927SAndroid Build Coastguard Worker } else {
2603*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, func, target, GL_INVALID_OPERATION);
2604*61046927SAndroid Build Coastguard Worker if (!bufObj)
2605*61046927SAndroid Build Coastguard Worker return;
2606*61046927SAndroid Build Coastguard Worker }
2607*61046927SAndroid Build Coastguard Worker }
2608*61046927SAndroid Build Coastguard Worker
2609*61046927SAndroid Build Coastguard Worker if (no_error || validate_buffer_sub_data(ctx, bufObj, offset, size, func))
2610*61046927SAndroid Build Coastguard Worker _mesa_buffer_sub_data(ctx, bufObj, offset, size, data);
2611*61046927SAndroid Build Coastguard Worker }
2612*61046927SAndroid Build Coastguard Worker
2613*61046927SAndroid Build Coastguard Worker
2614*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BufferSubData_no_error(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)2615*61046927SAndroid Build Coastguard Worker _mesa_BufferSubData_no_error(GLenum target, GLintptr offset,
2616*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid *data)
2617*61046927SAndroid Build Coastguard Worker {
2618*61046927SAndroid Build Coastguard Worker buffer_sub_data(target, 0, offset, size, data, false, true,
2619*61046927SAndroid Build Coastguard Worker "glBufferSubData");
2620*61046927SAndroid Build Coastguard Worker }
2621*61046927SAndroid Build Coastguard Worker
2622*61046927SAndroid Build Coastguard Worker
2623*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)2624*61046927SAndroid Build Coastguard Worker _mesa_BufferSubData(GLenum target, GLintptr offset,
2625*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid *data)
2626*61046927SAndroid Build Coastguard Worker {
2627*61046927SAndroid Build Coastguard Worker buffer_sub_data(target, 0, offset, size, data, false, false,
2628*61046927SAndroid Build Coastguard Worker "glBufferSubData");
2629*61046927SAndroid Build Coastguard Worker }
2630*61046927SAndroid Build Coastguard Worker
2631*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferSubData_no_error(GLuint buffer,GLintptr offset,GLsizeiptr size,const GLvoid * data)2632*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferSubData_no_error(GLuint buffer, GLintptr offset,
2633*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid *data)
2634*61046927SAndroid Build Coastguard Worker {
2635*61046927SAndroid Build Coastguard Worker buffer_sub_data(0, buffer, offset, size, data, true, true,
2636*61046927SAndroid Build Coastguard Worker "glNamedBufferSubData");
2637*61046927SAndroid Build Coastguard Worker }
2638*61046927SAndroid Build Coastguard Worker
2639*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferSubData(GLuint buffer,GLintptr offset,GLsizeiptr size,const GLvoid * data)2640*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferSubData(GLuint buffer, GLintptr offset,
2641*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid *data)
2642*61046927SAndroid Build Coastguard Worker {
2643*61046927SAndroid Build Coastguard Worker buffer_sub_data(0, buffer, offset, size, data, true, false,
2644*61046927SAndroid Build Coastguard Worker "glNamedBufferSubData");
2645*61046927SAndroid Build Coastguard Worker }
2646*61046927SAndroid Build Coastguard Worker
2647*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferSubDataEXT(GLuint buffer,GLintptr offset,GLsizeiptr size,const GLvoid * data)2648*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferSubDataEXT(GLuint buffer, GLintptr offset,
2649*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid *data)
2650*61046927SAndroid Build Coastguard Worker {
2651*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2652*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2653*61046927SAndroid Build Coastguard Worker
2654*61046927SAndroid Build Coastguard Worker if (!buffer) {
2655*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
2656*61046927SAndroid Build Coastguard Worker "glNamedBufferSubDataEXT(buffer=0)");
2657*61046927SAndroid Build Coastguard Worker return;
2658*61046927SAndroid Build Coastguard Worker }
2659*61046927SAndroid Build Coastguard Worker
2660*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2661*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
2662*61046927SAndroid Build Coastguard Worker &bufObj, "glNamedBufferSubDataEXT", false))
2663*61046927SAndroid Build Coastguard Worker return;
2664*61046927SAndroid Build Coastguard Worker
2665*61046927SAndroid Build Coastguard Worker if (validate_buffer_sub_data(ctx, bufObj, offset, size,
2666*61046927SAndroid Build Coastguard Worker "glNamedBufferSubDataEXT")) {
2667*61046927SAndroid Build Coastguard Worker _mesa_buffer_sub_data(ctx, bufObj, offset, size, data);
2668*61046927SAndroid Build Coastguard Worker }
2669*61046927SAndroid Build Coastguard Worker }
2670*61046927SAndroid Build Coastguard Worker
2671*61046927SAndroid Build Coastguard Worker
2672*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,GLvoid * data)2673*61046927SAndroid Build Coastguard Worker _mesa_GetBufferSubData(GLenum target, GLintptr offset,
2674*61046927SAndroid Build Coastguard Worker GLsizeiptr size, GLvoid *data)
2675*61046927SAndroid Build Coastguard Worker {
2676*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2677*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2678*61046927SAndroid Build Coastguard Worker
2679*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glGetBufferSubData", target,
2680*61046927SAndroid Build Coastguard Worker GL_INVALID_OPERATION);
2681*61046927SAndroid Build Coastguard Worker if (!bufObj)
2682*61046927SAndroid Build Coastguard Worker return;
2683*61046927SAndroid Build Coastguard Worker
2684*61046927SAndroid Build Coastguard Worker if (!buffer_object_subdata_range_good(ctx, bufObj, offset, size, false,
2685*61046927SAndroid Build Coastguard Worker "glGetBufferSubData")) {
2686*61046927SAndroid Build Coastguard Worker return;
2687*61046927SAndroid Build Coastguard Worker }
2688*61046927SAndroid Build Coastguard Worker
2689*61046927SAndroid Build Coastguard Worker bufferobj_get_subdata(ctx, offset, size, data, bufObj);
2690*61046927SAndroid Build Coastguard Worker }
2691*61046927SAndroid Build Coastguard Worker
2692*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedBufferSubData(GLuint buffer,GLintptr offset,GLsizeiptr size,GLvoid * data)2693*61046927SAndroid Build Coastguard Worker _mesa_GetNamedBufferSubData(GLuint buffer, GLintptr offset,
2694*61046927SAndroid Build Coastguard Worker GLsizeiptr size, GLvoid *data)
2695*61046927SAndroid Build Coastguard Worker {
2696*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2697*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2698*61046927SAndroid Build Coastguard Worker
2699*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
2700*61046927SAndroid Build Coastguard Worker "glGetNamedBufferSubData");
2701*61046927SAndroid Build Coastguard Worker if (!bufObj)
2702*61046927SAndroid Build Coastguard Worker return;
2703*61046927SAndroid Build Coastguard Worker
2704*61046927SAndroid Build Coastguard Worker if (!buffer_object_subdata_range_good(ctx, bufObj, offset, size, false,
2705*61046927SAndroid Build Coastguard Worker "glGetNamedBufferSubData")) {
2706*61046927SAndroid Build Coastguard Worker return;
2707*61046927SAndroid Build Coastguard Worker }
2708*61046927SAndroid Build Coastguard Worker
2709*61046927SAndroid Build Coastguard Worker bufferobj_get_subdata(ctx, offset, size, data, bufObj);
2710*61046927SAndroid Build Coastguard Worker }
2711*61046927SAndroid Build Coastguard Worker
2712*61046927SAndroid Build Coastguard Worker
2713*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedBufferSubDataEXT(GLuint buffer,GLintptr offset,GLsizeiptr size,GLvoid * data)2714*61046927SAndroid Build Coastguard Worker _mesa_GetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset,
2715*61046927SAndroid Build Coastguard Worker GLsizeiptr size, GLvoid *data)
2716*61046927SAndroid Build Coastguard Worker {
2717*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2718*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2719*61046927SAndroid Build Coastguard Worker
2720*61046927SAndroid Build Coastguard Worker if (!buffer) {
2721*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
2722*61046927SAndroid Build Coastguard Worker "glGetNamedBufferSubDataEXT(buffer=0)");
2723*61046927SAndroid Build Coastguard Worker return;
2724*61046927SAndroid Build Coastguard Worker }
2725*61046927SAndroid Build Coastguard Worker
2726*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2727*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
2728*61046927SAndroid Build Coastguard Worker &bufObj, "glGetNamedBufferSubDataEXT", false))
2729*61046927SAndroid Build Coastguard Worker return;
2730*61046927SAndroid Build Coastguard Worker
2731*61046927SAndroid Build Coastguard Worker if (!buffer_object_subdata_range_good(ctx, bufObj, offset, size, false,
2732*61046927SAndroid Build Coastguard Worker "glGetNamedBufferSubDataEXT")) {
2733*61046927SAndroid Build Coastguard Worker return;
2734*61046927SAndroid Build Coastguard Worker }
2735*61046927SAndroid Build Coastguard Worker
2736*61046927SAndroid Build Coastguard Worker bufferobj_get_subdata(ctx, offset, size, data, bufObj);
2737*61046927SAndroid Build Coastguard Worker }
2738*61046927SAndroid Build Coastguard Worker
2739*61046927SAndroid Build Coastguard Worker /**
2740*61046927SAndroid Build Coastguard Worker * \param subdata true if caller is *SubData, false if *Data
2741*61046927SAndroid Build Coastguard Worker */
2742*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
clear_buffer_sub_data(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLenum internalformat,GLintptr offset,GLsizeiptr size,GLenum format,GLenum type,const GLvoid * data,const char * func,bool subdata,bool no_error)2743*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
2744*61046927SAndroid Build Coastguard Worker GLenum internalformat, GLintptr offset, GLsizeiptr size,
2745*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type, const GLvoid *data,
2746*61046927SAndroid Build Coastguard Worker const char *func, bool subdata, bool no_error)
2747*61046927SAndroid Build Coastguard Worker {
2748*61046927SAndroid Build Coastguard Worker mesa_format mesaFormat;
2749*61046927SAndroid Build Coastguard Worker GLubyte clearValue[MAX_PIXEL_BYTES];
2750*61046927SAndroid Build Coastguard Worker GLsizeiptr clearValueSize;
2751*61046927SAndroid Build Coastguard Worker
2752*61046927SAndroid Build Coastguard Worker /* This checks for disallowed mappings. */
2753*61046927SAndroid Build Coastguard Worker if (!no_error && !buffer_object_subdata_range_good(ctx, bufObj, offset, size,
2754*61046927SAndroid Build Coastguard Worker subdata, func)) {
2755*61046927SAndroid Build Coastguard Worker return;
2756*61046927SAndroid Build Coastguard Worker }
2757*61046927SAndroid Build Coastguard Worker
2758*61046927SAndroid Build Coastguard Worker if (no_error) {
2759*61046927SAndroid Build Coastguard Worker mesaFormat = _mesa_get_texbuffer_format(ctx, internalformat);
2760*61046927SAndroid Build Coastguard Worker } else {
2761*61046927SAndroid Build Coastguard Worker mesaFormat = validate_clear_buffer_format(ctx, internalformat,
2762*61046927SAndroid Build Coastguard Worker format, type, func);
2763*61046927SAndroid Build Coastguard Worker }
2764*61046927SAndroid Build Coastguard Worker
2765*61046927SAndroid Build Coastguard Worker if (mesaFormat == MESA_FORMAT_NONE)
2766*61046927SAndroid Build Coastguard Worker return;
2767*61046927SAndroid Build Coastguard Worker
2768*61046927SAndroid Build Coastguard Worker clearValueSize = _mesa_get_format_bytes(mesaFormat);
2769*61046927SAndroid Build Coastguard Worker if (!no_error &&
2770*61046927SAndroid Build Coastguard Worker (offset % clearValueSize != 0 || size % clearValueSize != 0)) {
2771*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
2772*61046927SAndroid Build Coastguard Worker "%s(offset or size is not a multiple of "
2773*61046927SAndroid Build Coastguard Worker "internalformat size)", func);
2774*61046927SAndroid Build Coastguard Worker return;
2775*61046927SAndroid Build Coastguard Worker }
2776*61046927SAndroid Build Coastguard Worker
2777*61046927SAndroid Build Coastguard Worker /* Bail early. Negative size has already been checked. */
2778*61046927SAndroid Build Coastguard Worker if (size == 0)
2779*61046927SAndroid Build Coastguard Worker return;
2780*61046927SAndroid Build Coastguard Worker
2781*61046927SAndroid Build Coastguard Worker bufObj->MinMaxCacheDirty = true;
2782*61046927SAndroid Build Coastguard Worker
2783*61046927SAndroid Build Coastguard Worker if (!ctx->pipe->clear_buffer) {
2784*61046927SAndroid Build Coastguard Worker clear_buffer_subdata_sw(ctx, offset, size,
2785*61046927SAndroid Build Coastguard Worker data, clearValueSize, bufObj);
2786*61046927SAndroid Build Coastguard Worker return;
2787*61046927SAndroid Build Coastguard Worker }
2788*61046927SAndroid Build Coastguard Worker
2789*61046927SAndroid Build Coastguard Worker if (!data)
2790*61046927SAndroid Build Coastguard Worker memset(clearValue, 0, MAX_PIXEL_BYTES);
2791*61046927SAndroid Build Coastguard Worker else if (!convert_clear_buffer_data(ctx, mesaFormat, clearValue,
2792*61046927SAndroid Build Coastguard Worker format, type, data, func)) {
2793*61046927SAndroid Build Coastguard Worker return;
2794*61046927SAndroid Build Coastguard Worker }
2795*61046927SAndroid Build Coastguard Worker
2796*61046927SAndroid Build Coastguard Worker ctx->pipe->clear_buffer(ctx->pipe, bufObj->buffer, offset, size,
2797*61046927SAndroid Build Coastguard Worker clearValue, clearValueSize);
2798*61046927SAndroid Build Coastguard Worker }
2799*61046927SAndroid Build Coastguard Worker
2800*61046927SAndroid Build Coastguard Worker static void
clear_buffer_sub_data_error(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLenum internalformat,GLintptr offset,GLsizeiptr size,GLenum format,GLenum type,const GLvoid * data,const char * func,bool subdata)2801*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_error(struct gl_context *ctx,
2802*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
2803*61046927SAndroid Build Coastguard Worker GLenum internalformat, GLintptr offset,
2804*61046927SAndroid Build Coastguard Worker GLsizeiptr size, GLenum format, GLenum type,
2805*61046927SAndroid Build Coastguard Worker const GLvoid *data, const char *func, bool subdata)
2806*61046927SAndroid Build Coastguard Worker {
2807*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data(ctx, bufObj, internalformat, offset, size, format,
2808*61046927SAndroid Build Coastguard Worker type, data, func, subdata, false);
2809*61046927SAndroid Build Coastguard Worker }
2810*61046927SAndroid Build Coastguard Worker
2811*61046927SAndroid Build Coastguard Worker
2812*61046927SAndroid Build Coastguard Worker static void
clear_buffer_sub_data_no_error(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLenum internalformat,GLintptr offset,GLsizeiptr size,GLenum format,GLenum type,const GLvoid * data,const char * func,bool subdata)2813*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_no_error(struct gl_context *ctx,
2814*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
2815*61046927SAndroid Build Coastguard Worker GLenum internalformat, GLintptr offset,
2816*61046927SAndroid Build Coastguard Worker GLsizeiptr size, GLenum format, GLenum type,
2817*61046927SAndroid Build Coastguard Worker const GLvoid *data, const char *func,
2818*61046927SAndroid Build Coastguard Worker bool subdata)
2819*61046927SAndroid Build Coastguard Worker {
2820*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data(ctx, bufObj, internalformat, offset, size, format,
2821*61046927SAndroid Build Coastguard Worker type, data, func, subdata, true);
2822*61046927SAndroid Build Coastguard Worker }
2823*61046927SAndroid Build Coastguard Worker
2824*61046927SAndroid Build Coastguard Worker
2825*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferData_no_error(GLenum target,GLenum internalformat,GLenum format,GLenum type,const GLvoid * data)2826*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferData_no_error(GLenum target, GLenum internalformat,
2827*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type, const GLvoid *data)
2828*61046927SAndroid Build Coastguard Worker {
2829*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2830*61046927SAndroid Build Coastguard Worker
2831*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObj = get_buffer_target(ctx, target, true);
2832*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_no_error(ctx, *bufObj, internalformat, 0,
2833*61046927SAndroid Build Coastguard Worker (*bufObj)->Size, format, type, data,
2834*61046927SAndroid Build Coastguard Worker "glClearBufferData", false);
2835*61046927SAndroid Build Coastguard Worker }
2836*61046927SAndroid Build Coastguard Worker
2837*61046927SAndroid Build Coastguard Worker
2838*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferData(GLenum target,GLenum internalformat,GLenum format,GLenum type,const GLvoid * data)2839*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferData(GLenum target, GLenum internalformat, GLenum format,
2840*61046927SAndroid Build Coastguard Worker GLenum type, const GLvoid *data)
2841*61046927SAndroid Build Coastguard Worker {
2842*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2843*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2844*61046927SAndroid Build Coastguard Worker
2845*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glClearBufferData", target, GL_INVALID_VALUE);
2846*61046927SAndroid Build Coastguard Worker if (!bufObj)
2847*61046927SAndroid Build Coastguard Worker return;
2848*61046927SAndroid Build Coastguard Worker
2849*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_error(ctx, bufObj, internalformat, 0, bufObj->Size,
2850*61046927SAndroid Build Coastguard Worker format, type, data, "glClearBufferData", false);
2851*61046927SAndroid Build Coastguard Worker }
2852*61046927SAndroid Build Coastguard Worker
2853*61046927SAndroid Build Coastguard Worker
2854*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedBufferData_no_error(GLuint buffer,GLenum internalformat,GLenum format,GLenum type,const GLvoid * data)2855*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedBufferData_no_error(GLuint buffer, GLenum internalformat,
2856*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type,
2857*61046927SAndroid Build Coastguard Worker const GLvoid *data)
2858*61046927SAndroid Build Coastguard Worker {
2859*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2860*61046927SAndroid Build Coastguard Worker
2861*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2862*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_no_error(ctx, bufObj, internalformat, 0, bufObj->Size,
2863*61046927SAndroid Build Coastguard Worker format, type, data, "glClearNamedBufferData",
2864*61046927SAndroid Build Coastguard Worker false);
2865*61046927SAndroid Build Coastguard Worker }
2866*61046927SAndroid Build Coastguard Worker
2867*61046927SAndroid Build Coastguard Worker
2868*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedBufferData(GLuint buffer,GLenum internalformat,GLenum format,GLenum type,const GLvoid * data)2869*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedBufferData(GLuint buffer, GLenum internalformat,
2870*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type, const GLvoid *data)
2871*61046927SAndroid Build Coastguard Worker {
2872*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2873*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2874*61046927SAndroid Build Coastguard Worker
2875*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glClearNamedBufferData");
2876*61046927SAndroid Build Coastguard Worker if (!bufObj)
2877*61046927SAndroid Build Coastguard Worker return;
2878*61046927SAndroid Build Coastguard Worker
2879*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_error(ctx, bufObj, internalformat, 0, bufObj->Size,
2880*61046927SAndroid Build Coastguard Worker format, type, data, "glClearNamedBufferData",
2881*61046927SAndroid Build Coastguard Worker false);
2882*61046927SAndroid Build Coastguard Worker }
2883*61046927SAndroid Build Coastguard Worker
2884*61046927SAndroid Build Coastguard Worker
2885*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedBufferDataEXT(GLuint buffer,GLenum internalformat,GLenum format,GLenum type,const GLvoid * data)2886*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat,
2887*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type, const GLvoid *data)
2888*61046927SAndroid Build Coastguard Worker {
2889*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2890*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2891*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
2892*61046927SAndroid Build Coastguard Worker &bufObj, "glClearNamedBufferDataEXT", false))
2893*61046927SAndroid Build Coastguard Worker return;
2894*61046927SAndroid Build Coastguard Worker
2895*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_error(ctx, bufObj, internalformat, 0, bufObj->Size,
2896*61046927SAndroid Build Coastguard Worker format, type, data, "glClearNamedBufferDataEXT",
2897*61046927SAndroid Build Coastguard Worker false);
2898*61046927SAndroid Build Coastguard Worker }
2899*61046927SAndroid Build Coastguard Worker
2900*61046927SAndroid Build Coastguard Worker
2901*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferSubData_no_error(GLenum target,GLenum internalformat,GLintptr offset,GLsizeiptr size,GLenum format,GLenum type,const GLvoid * data)2902*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferSubData_no_error(GLenum target, GLenum internalformat,
2903*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size,
2904*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type,
2905*61046927SAndroid Build Coastguard Worker const GLvoid *data)
2906*61046927SAndroid Build Coastguard Worker {
2907*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2908*61046927SAndroid Build Coastguard Worker
2909*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObj = get_buffer_target(ctx, target, true);
2910*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_no_error(ctx, *bufObj, internalformat, offset, size,
2911*61046927SAndroid Build Coastguard Worker format, type, data, "glClearBufferSubData",
2912*61046927SAndroid Build Coastguard Worker true);
2913*61046927SAndroid Build Coastguard Worker }
2914*61046927SAndroid Build Coastguard Worker
2915*61046927SAndroid Build Coastguard Worker
2916*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearBufferSubData(GLenum target,GLenum internalformat,GLintptr offset,GLsizeiptr size,GLenum format,GLenum type,const GLvoid * data)2917*61046927SAndroid Build Coastguard Worker _mesa_ClearBufferSubData(GLenum target, GLenum internalformat,
2918*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size,
2919*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type,
2920*61046927SAndroid Build Coastguard Worker const GLvoid *data)
2921*61046927SAndroid Build Coastguard Worker {
2922*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2923*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2924*61046927SAndroid Build Coastguard Worker
2925*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glClearBufferSubData", target, GL_INVALID_VALUE);
2926*61046927SAndroid Build Coastguard Worker if (!bufObj)
2927*61046927SAndroid Build Coastguard Worker return;
2928*61046927SAndroid Build Coastguard Worker
2929*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_error(ctx, bufObj, internalformat, offset, size,
2930*61046927SAndroid Build Coastguard Worker format, type, data, "glClearBufferSubData",
2931*61046927SAndroid Build Coastguard Worker true);
2932*61046927SAndroid Build Coastguard Worker }
2933*61046927SAndroid Build Coastguard Worker
2934*61046927SAndroid Build Coastguard Worker
2935*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedBufferSubData_no_error(GLuint buffer,GLenum internalformat,GLintptr offset,GLsizeiptr size,GLenum format,GLenum type,const GLvoid * data)2936*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedBufferSubData_no_error(GLuint buffer, GLenum internalformat,
2937*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size,
2938*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type,
2939*61046927SAndroid Build Coastguard Worker const GLvoid *data)
2940*61046927SAndroid Build Coastguard Worker {
2941*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2942*61046927SAndroid Build Coastguard Worker
2943*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2944*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_no_error(ctx, bufObj, internalformat, offset, size,
2945*61046927SAndroid Build Coastguard Worker format, type, data,
2946*61046927SAndroid Build Coastguard Worker "glClearNamedBufferSubData", true);
2947*61046927SAndroid Build Coastguard Worker }
2948*61046927SAndroid Build Coastguard Worker
2949*61046927SAndroid Build Coastguard Worker
2950*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedBufferSubData(GLuint buffer,GLenum internalformat,GLintptr offset,GLsizeiptr size,GLenum format,GLenum type,const GLvoid * data)2951*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedBufferSubData(GLuint buffer, GLenum internalformat,
2952*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size,
2953*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type,
2954*61046927SAndroid Build Coastguard Worker const GLvoid *data)
2955*61046927SAndroid Build Coastguard Worker {
2956*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2957*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
2958*61046927SAndroid Build Coastguard Worker
2959*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
2960*61046927SAndroid Build Coastguard Worker "glClearNamedBufferSubData");
2961*61046927SAndroid Build Coastguard Worker if (!bufObj)
2962*61046927SAndroid Build Coastguard Worker return;
2963*61046927SAndroid Build Coastguard Worker
2964*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_error(ctx, bufObj, internalformat, offset, size,
2965*61046927SAndroid Build Coastguard Worker format, type, data, "glClearNamedBufferSubData",
2966*61046927SAndroid Build Coastguard Worker true);
2967*61046927SAndroid Build Coastguard Worker }
2968*61046927SAndroid Build Coastguard Worker
2969*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ClearNamedBufferSubDataEXT(GLuint buffer,GLenum internalformat,GLintptr offset,GLsizeiptr size,GLenum format,GLenum type,const GLvoid * data)2970*61046927SAndroid Build Coastguard Worker _mesa_ClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat,
2971*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size,
2972*61046927SAndroid Build Coastguard Worker GLenum format, GLenum type,
2973*61046927SAndroid Build Coastguard Worker const GLvoid *data)
2974*61046927SAndroid Build Coastguard Worker {
2975*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
2976*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
2977*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
2978*61046927SAndroid Build Coastguard Worker &bufObj, "glClearNamedBufferSubDataEXT", false))
2979*61046927SAndroid Build Coastguard Worker return;
2980*61046927SAndroid Build Coastguard Worker
2981*61046927SAndroid Build Coastguard Worker clear_buffer_sub_data_error(ctx, bufObj, internalformat, offset, size,
2982*61046927SAndroid Build Coastguard Worker format, type, data, "glClearNamedBufferSubDataEXT",
2983*61046927SAndroid Build Coastguard Worker true);
2984*61046927SAndroid Build Coastguard Worker }
2985*61046927SAndroid Build Coastguard Worker
2986*61046927SAndroid Build Coastguard Worker static GLboolean
unmap_buffer(struct gl_context * ctx,struct gl_buffer_object * bufObj)2987*61046927SAndroid Build Coastguard Worker unmap_buffer(struct gl_context *ctx, struct gl_buffer_object *bufObj)
2988*61046927SAndroid Build Coastguard Worker {
2989*61046927SAndroid Build Coastguard Worker GLboolean status = _mesa_bufferobj_unmap(ctx, bufObj, MAP_USER);
2990*61046927SAndroid Build Coastguard Worker bufObj->Mappings[MAP_USER].AccessFlags = 0;
2991*61046927SAndroid Build Coastguard Worker assert(bufObj->Mappings[MAP_USER].Pointer == NULL);
2992*61046927SAndroid Build Coastguard Worker assert(bufObj->Mappings[MAP_USER].Offset == 0);
2993*61046927SAndroid Build Coastguard Worker assert(bufObj->Mappings[MAP_USER].Length == 0);
2994*61046927SAndroid Build Coastguard Worker
2995*61046927SAndroid Build Coastguard Worker return status;
2996*61046927SAndroid Build Coastguard Worker }
2997*61046927SAndroid Build Coastguard Worker
2998*61046927SAndroid Build Coastguard Worker static GLboolean
validate_and_unmap_buffer(struct gl_context * ctx,struct gl_buffer_object * bufObj,const char * func)2999*61046927SAndroid Build Coastguard Worker validate_and_unmap_buffer(struct gl_context *ctx,
3000*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
3001*61046927SAndroid Build Coastguard Worker const char *func)
3002*61046927SAndroid Build Coastguard Worker {
3003*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
3004*61046927SAndroid Build Coastguard Worker
3005*61046927SAndroid Build Coastguard Worker if (!_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
3006*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3007*61046927SAndroid Build Coastguard Worker "%s(buffer is not mapped)", func);
3008*61046927SAndroid Build Coastguard Worker return GL_FALSE;
3009*61046927SAndroid Build Coastguard Worker }
3010*61046927SAndroid Build Coastguard Worker
3011*61046927SAndroid Build Coastguard Worker #ifdef BOUNDS_CHECK
3012*61046927SAndroid Build Coastguard Worker if (bufObj->Mappings[MAP_USER].AccessFlags != GL_READ_ONLY_ARB) {
3013*61046927SAndroid Build Coastguard Worker GLubyte *buf = (GLubyte *) bufObj->Mappings[MAP_USER].Pointer;
3014*61046927SAndroid Build Coastguard Worker GLuint i;
3015*61046927SAndroid Build Coastguard Worker /* check that last 100 bytes are still = magic value */
3016*61046927SAndroid Build Coastguard Worker for (i = 0; i < 100; i++) {
3017*61046927SAndroid Build Coastguard Worker GLuint pos = bufObj->Size - i - 1;
3018*61046927SAndroid Build Coastguard Worker if (buf[pos] != 123) {
3019*61046927SAndroid Build Coastguard Worker _mesa_warning(ctx, "Out of bounds buffer object write detected"
3020*61046927SAndroid Build Coastguard Worker " at position %d (value = %u)\n",
3021*61046927SAndroid Build Coastguard Worker pos, buf[pos]);
3022*61046927SAndroid Build Coastguard Worker }
3023*61046927SAndroid Build Coastguard Worker }
3024*61046927SAndroid Build Coastguard Worker }
3025*61046927SAndroid Build Coastguard Worker #endif
3026*61046927SAndroid Build Coastguard Worker
3027*61046927SAndroid Build Coastguard Worker #ifdef VBO_DEBUG
3028*61046927SAndroid Build Coastguard Worker if (bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_WRITE_BIT) {
3029*61046927SAndroid Build Coastguard Worker GLuint i, unchanged = 0;
3030*61046927SAndroid Build Coastguard Worker GLubyte *b = (GLubyte *) bufObj->Mappings[MAP_USER].Pointer;
3031*61046927SAndroid Build Coastguard Worker GLint pos = -1;
3032*61046927SAndroid Build Coastguard Worker /* check which bytes changed */
3033*61046927SAndroid Build Coastguard Worker for (i = 0; i < bufObj->Size - 1; i++) {
3034*61046927SAndroid Build Coastguard Worker if (b[i] == (i & 0xff) && b[i+1] == ((i+1) & 0xff)) {
3035*61046927SAndroid Build Coastguard Worker unchanged++;
3036*61046927SAndroid Build Coastguard Worker if (pos == -1)
3037*61046927SAndroid Build Coastguard Worker pos = i;
3038*61046927SAndroid Build Coastguard Worker }
3039*61046927SAndroid Build Coastguard Worker }
3040*61046927SAndroid Build Coastguard Worker if (unchanged) {
3041*61046927SAndroid Build Coastguard Worker printf("glUnmapBufferARB(%u): %u of %ld unchanged, starting at %d\n",
3042*61046927SAndroid Build Coastguard Worker bufObj->Name, unchanged, bufObj->Size, pos);
3043*61046927SAndroid Build Coastguard Worker }
3044*61046927SAndroid Build Coastguard Worker }
3045*61046927SAndroid Build Coastguard Worker #endif
3046*61046927SAndroid Build Coastguard Worker
3047*61046927SAndroid Build Coastguard Worker return unmap_buffer(ctx, bufObj);
3048*61046927SAndroid Build Coastguard Worker }
3049*61046927SAndroid Build Coastguard Worker
3050*61046927SAndroid Build Coastguard Worker GLboolean GLAPIENTRY
_mesa_UnmapBuffer_no_error(GLenum target)3051*61046927SAndroid Build Coastguard Worker _mesa_UnmapBuffer_no_error(GLenum target)
3052*61046927SAndroid Build Coastguard Worker {
3053*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3054*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true);
3055*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = *bufObjPtr;
3056*61046927SAndroid Build Coastguard Worker
3057*61046927SAndroid Build Coastguard Worker return unmap_buffer(ctx, bufObj);
3058*61046927SAndroid Build Coastguard Worker }
3059*61046927SAndroid Build Coastguard Worker
3060*61046927SAndroid Build Coastguard Worker GLboolean GLAPIENTRY
_mesa_UnmapBuffer(GLenum target)3061*61046927SAndroid Build Coastguard Worker _mesa_UnmapBuffer(GLenum target)
3062*61046927SAndroid Build Coastguard Worker {
3063*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3064*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3065*61046927SAndroid Build Coastguard Worker
3066*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glUnmapBuffer", target, GL_INVALID_OPERATION);
3067*61046927SAndroid Build Coastguard Worker if (!bufObj)
3068*61046927SAndroid Build Coastguard Worker return GL_FALSE;
3069*61046927SAndroid Build Coastguard Worker
3070*61046927SAndroid Build Coastguard Worker return validate_and_unmap_buffer(ctx, bufObj, "glUnmapBuffer");
3071*61046927SAndroid Build Coastguard Worker }
3072*61046927SAndroid Build Coastguard Worker
3073*61046927SAndroid Build Coastguard Worker GLboolean GLAPIENTRY
_mesa_UnmapNamedBufferEXT_no_error(GLuint buffer)3074*61046927SAndroid Build Coastguard Worker _mesa_UnmapNamedBufferEXT_no_error(GLuint buffer)
3075*61046927SAndroid Build Coastguard Worker {
3076*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3077*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
3078*61046927SAndroid Build Coastguard Worker
3079*61046927SAndroid Build Coastguard Worker return unmap_buffer(ctx, bufObj);
3080*61046927SAndroid Build Coastguard Worker }
3081*61046927SAndroid Build Coastguard Worker
3082*61046927SAndroid Build Coastguard Worker GLboolean GLAPIENTRY
_mesa_UnmapNamedBufferEXT(GLuint buffer)3083*61046927SAndroid Build Coastguard Worker _mesa_UnmapNamedBufferEXT(GLuint buffer)
3084*61046927SAndroid Build Coastguard Worker {
3085*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3086*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3087*61046927SAndroid Build Coastguard Worker
3088*61046927SAndroid Build Coastguard Worker if (!buffer) {
3089*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3090*61046927SAndroid Build Coastguard Worker "glUnmapNamedBufferEXT(buffer=0)");
3091*61046927SAndroid Build Coastguard Worker return GL_FALSE;
3092*61046927SAndroid Build Coastguard Worker }
3093*61046927SAndroid Build Coastguard Worker
3094*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glUnmapNamedBuffer");
3095*61046927SAndroid Build Coastguard Worker if (!bufObj)
3096*61046927SAndroid Build Coastguard Worker return GL_FALSE;
3097*61046927SAndroid Build Coastguard Worker
3098*61046927SAndroid Build Coastguard Worker return validate_and_unmap_buffer(ctx, bufObj, "glUnmapNamedBuffer");
3099*61046927SAndroid Build Coastguard Worker }
3100*61046927SAndroid Build Coastguard Worker
3101*61046927SAndroid Build Coastguard Worker
3102*61046927SAndroid Build Coastguard Worker static bool
get_buffer_parameter(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLenum pname,GLint64 * params,const char * func)3103*61046927SAndroid Build Coastguard Worker get_buffer_parameter(struct gl_context *ctx,
3104*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj, GLenum pname,
3105*61046927SAndroid Build Coastguard Worker GLint64 *params, const char *func)
3106*61046927SAndroid Build Coastguard Worker {
3107*61046927SAndroid Build Coastguard Worker switch (pname) {
3108*61046927SAndroid Build Coastguard Worker case GL_BUFFER_SIZE_ARB:
3109*61046927SAndroid Build Coastguard Worker *params = bufObj->Size;
3110*61046927SAndroid Build Coastguard Worker break;
3111*61046927SAndroid Build Coastguard Worker case GL_BUFFER_USAGE_ARB:
3112*61046927SAndroid Build Coastguard Worker *params = bufObj->Usage;
3113*61046927SAndroid Build Coastguard Worker break;
3114*61046927SAndroid Build Coastguard Worker case GL_BUFFER_ACCESS_ARB:
3115*61046927SAndroid Build Coastguard Worker *params = simplified_access_mode(ctx,
3116*61046927SAndroid Build Coastguard Worker bufObj->Mappings[MAP_USER].AccessFlags);
3117*61046927SAndroid Build Coastguard Worker break;
3118*61046927SAndroid Build Coastguard Worker case GL_BUFFER_MAPPED_ARB:
3119*61046927SAndroid Build Coastguard Worker *params = _mesa_bufferobj_mapped(bufObj, MAP_USER);
3120*61046927SAndroid Build Coastguard Worker break;
3121*61046927SAndroid Build Coastguard Worker case GL_BUFFER_ACCESS_FLAGS:
3122*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_map_buffer_range)
3123*61046927SAndroid Build Coastguard Worker goto invalid_pname;
3124*61046927SAndroid Build Coastguard Worker *params = bufObj->Mappings[MAP_USER].AccessFlags;
3125*61046927SAndroid Build Coastguard Worker break;
3126*61046927SAndroid Build Coastguard Worker case GL_BUFFER_MAP_OFFSET:
3127*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_map_buffer_range)
3128*61046927SAndroid Build Coastguard Worker goto invalid_pname;
3129*61046927SAndroid Build Coastguard Worker *params = bufObj->Mappings[MAP_USER].Offset;
3130*61046927SAndroid Build Coastguard Worker break;
3131*61046927SAndroid Build Coastguard Worker case GL_BUFFER_MAP_LENGTH:
3132*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_map_buffer_range)
3133*61046927SAndroid Build Coastguard Worker goto invalid_pname;
3134*61046927SAndroid Build Coastguard Worker *params = bufObj->Mappings[MAP_USER].Length;
3135*61046927SAndroid Build Coastguard Worker break;
3136*61046927SAndroid Build Coastguard Worker case GL_BUFFER_IMMUTABLE_STORAGE:
3137*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_buffer_storage)
3138*61046927SAndroid Build Coastguard Worker goto invalid_pname;
3139*61046927SAndroid Build Coastguard Worker *params = bufObj->Immutable;
3140*61046927SAndroid Build Coastguard Worker break;
3141*61046927SAndroid Build Coastguard Worker case GL_BUFFER_STORAGE_FLAGS:
3142*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_buffer_storage)
3143*61046927SAndroid Build Coastguard Worker goto invalid_pname;
3144*61046927SAndroid Build Coastguard Worker *params = bufObj->StorageFlags;
3145*61046927SAndroid Build Coastguard Worker break;
3146*61046927SAndroid Build Coastguard Worker default:
3147*61046927SAndroid Build Coastguard Worker goto invalid_pname;
3148*61046927SAndroid Build Coastguard Worker }
3149*61046927SAndroid Build Coastguard Worker
3150*61046927SAndroid Build Coastguard Worker return true;
3151*61046927SAndroid Build Coastguard Worker
3152*61046927SAndroid Build Coastguard Worker invalid_pname:
3153*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "%s(invalid pname: %s)", func,
3154*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(pname));
3155*61046927SAndroid Build Coastguard Worker return false;
3156*61046927SAndroid Build Coastguard Worker }
3157*61046927SAndroid Build Coastguard Worker
3158*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetBufferParameteriv(GLenum target,GLenum pname,GLint * params)3159*61046927SAndroid Build Coastguard Worker _mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params)
3160*61046927SAndroid Build Coastguard Worker {
3161*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3162*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3163*61046927SAndroid Build Coastguard Worker GLint64 parameter;
3164*61046927SAndroid Build Coastguard Worker
3165*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glGetBufferParameteriv", target,
3166*61046927SAndroid Build Coastguard Worker GL_INVALID_OPERATION);
3167*61046927SAndroid Build Coastguard Worker if (!bufObj)
3168*61046927SAndroid Build Coastguard Worker return;
3169*61046927SAndroid Build Coastguard Worker
3170*61046927SAndroid Build Coastguard Worker if (!get_buffer_parameter(ctx, bufObj, pname, ¶meter,
3171*61046927SAndroid Build Coastguard Worker "glGetBufferParameteriv"))
3172*61046927SAndroid Build Coastguard Worker return; /* Error already recorded. */
3173*61046927SAndroid Build Coastguard Worker
3174*61046927SAndroid Build Coastguard Worker *params = (GLint) parameter;
3175*61046927SAndroid Build Coastguard Worker }
3176*61046927SAndroid Build Coastguard Worker
3177*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetBufferParameteri64v(GLenum target,GLenum pname,GLint64 * params)3178*61046927SAndroid Build Coastguard Worker _mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params)
3179*61046927SAndroid Build Coastguard Worker {
3180*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3181*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3182*61046927SAndroid Build Coastguard Worker GLint64 parameter;
3183*61046927SAndroid Build Coastguard Worker
3184*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glGetBufferParameteri64v", target,
3185*61046927SAndroid Build Coastguard Worker GL_INVALID_OPERATION);
3186*61046927SAndroid Build Coastguard Worker if (!bufObj)
3187*61046927SAndroid Build Coastguard Worker return;
3188*61046927SAndroid Build Coastguard Worker
3189*61046927SAndroid Build Coastguard Worker if (!get_buffer_parameter(ctx, bufObj, pname, ¶meter,
3190*61046927SAndroid Build Coastguard Worker "glGetBufferParameteri64v"))
3191*61046927SAndroid Build Coastguard Worker return; /* Error already recorded. */
3192*61046927SAndroid Build Coastguard Worker
3193*61046927SAndroid Build Coastguard Worker *params = parameter;
3194*61046927SAndroid Build Coastguard Worker }
3195*61046927SAndroid Build Coastguard Worker
3196*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedBufferParameteriv(GLuint buffer,GLenum pname,GLint * params)3197*61046927SAndroid Build Coastguard Worker _mesa_GetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint *params)
3198*61046927SAndroid Build Coastguard Worker {
3199*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3200*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3201*61046927SAndroid Build Coastguard Worker GLint64 parameter;
3202*61046927SAndroid Build Coastguard Worker
3203*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
3204*61046927SAndroid Build Coastguard Worker "glGetNamedBufferParameteriv");
3205*61046927SAndroid Build Coastguard Worker if (!bufObj)
3206*61046927SAndroid Build Coastguard Worker return;
3207*61046927SAndroid Build Coastguard Worker
3208*61046927SAndroid Build Coastguard Worker if (!get_buffer_parameter(ctx, bufObj, pname, ¶meter,
3209*61046927SAndroid Build Coastguard Worker "glGetNamedBufferParameteriv"))
3210*61046927SAndroid Build Coastguard Worker return; /* Error already recorded. */
3211*61046927SAndroid Build Coastguard Worker
3212*61046927SAndroid Build Coastguard Worker *params = (GLint) parameter;
3213*61046927SAndroid Build Coastguard Worker }
3214*61046927SAndroid Build Coastguard Worker
3215*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedBufferParameterivEXT(GLuint buffer,GLenum pname,GLint * params)3216*61046927SAndroid Build Coastguard Worker _mesa_GetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint *params)
3217*61046927SAndroid Build Coastguard Worker {
3218*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3219*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3220*61046927SAndroid Build Coastguard Worker GLint64 parameter;
3221*61046927SAndroid Build Coastguard Worker
3222*61046927SAndroid Build Coastguard Worker if (!buffer) {
3223*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3224*61046927SAndroid Build Coastguard Worker "glGetNamedBufferParameterivEXT: buffer=0");
3225*61046927SAndroid Build Coastguard Worker return;
3226*61046927SAndroid Build Coastguard Worker }
3227*61046927SAndroid Build Coastguard Worker
3228*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
3229*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
3230*61046927SAndroid Build Coastguard Worker &bufObj, "glGetNamedBufferParameterivEXT", false))
3231*61046927SAndroid Build Coastguard Worker return;
3232*61046927SAndroid Build Coastguard Worker
3233*61046927SAndroid Build Coastguard Worker if (!get_buffer_parameter(ctx, bufObj, pname, ¶meter,
3234*61046927SAndroid Build Coastguard Worker "glGetNamedBufferParameterivEXT"))
3235*61046927SAndroid Build Coastguard Worker return; /* Error already recorded. */
3236*61046927SAndroid Build Coastguard Worker
3237*61046927SAndroid Build Coastguard Worker *params = (GLint) parameter;
3238*61046927SAndroid Build Coastguard Worker }
3239*61046927SAndroid Build Coastguard Worker
3240*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedBufferParameteri64v(GLuint buffer,GLenum pname,GLint64 * params)3241*61046927SAndroid Build Coastguard Worker _mesa_GetNamedBufferParameteri64v(GLuint buffer, GLenum pname,
3242*61046927SAndroid Build Coastguard Worker GLint64 *params)
3243*61046927SAndroid Build Coastguard Worker {
3244*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3245*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3246*61046927SAndroid Build Coastguard Worker GLint64 parameter;
3247*61046927SAndroid Build Coastguard Worker
3248*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
3249*61046927SAndroid Build Coastguard Worker "glGetNamedBufferParameteri64v");
3250*61046927SAndroid Build Coastguard Worker if (!bufObj)
3251*61046927SAndroid Build Coastguard Worker return;
3252*61046927SAndroid Build Coastguard Worker
3253*61046927SAndroid Build Coastguard Worker if (!get_buffer_parameter(ctx, bufObj, pname, ¶meter,
3254*61046927SAndroid Build Coastguard Worker "glGetNamedBufferParameteri64v"))
3255*61046927SAndroid Build Coastguard Worker return; /* Error already recorded. */
3256*61046927SAndroid Build Coastguard Worker
3257*61046927SAndroid Build Coastguard Worker *params = parameter;
3258*61046927SAndroid Build Coastguard Worker }
3259*61046927SAndroid Build Coastguard Worker
3260*61046927SAndroid Build Coastguard Worker
3261*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetBufferPointerv(GLenum target,GLenum pname,GLvoid ** params)3262*61046927SAndroid Build Coastguard Worker _mesa_GetBufferPointerv(GLenum target, GLenum pname, GLvoid **params)
3263*61046927SAndroid Build Coastguard Worker {
3264*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3265*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3266*61046927SAndroid Build Coastguard Worker
3267*61046927SAndroid Build Coastguard Worker if (pname != GL_BUFFER_MAP_POINTER) {
3268*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferPointerv(pname != "
3269*61046927SAndroid Build Coastguard Worker "GL_BUFFER_MAP_POINTER)");
3270*61046927SAndroid Build Coastguard Worker return;
3271*61046927SAndroid Build Coastguard Worker }
3272*61046927SAndroid Build Coastguard Worker
3273*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glGetBufferPointerv", target,
3274*61046927SAndroid Build Coastguard Worker GL_INVALID_OPERATION);
3275*61046927SAndroid Build Coastguard Worker if (!bufObj)
3276*61046927SAndroid Build Coastguard Worker return;
3277*61046927SAndroid Build Coastguard Worker
3278*61046927SAndroid Build Coastguard Worker *params = bufObj->Mappings[MAP_USER].Pointer;
3279*61046927SAndroid Build Coastguard Worker }
3280*61046927SAndroid Build Coastguard Worker
3281*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedBufferPointerv(GLuint buffer,GLenum pname,GLvoid ** params)3282*61046927SAndroid Build Coastguard Worker _mesa_GetNamedBufferPointerv(GLuint buffer, GLenum pname, GLvoid **params)
3283*61046927SAndroid Build Coastguard Worker {
3284*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3285*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3286*61046927SAndroid Build Coastguard Worker
3287*61046927SAndroid Build Coastguard Worker if (pname != GL_BUFFER_MAP_POINTER) {
3288*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetNamedBufferPointerv(pname != "
3289*61046927SAndroid Build Coastguard Worker "GL_BUFFER_MAP_POINTER)");
3290*61046927SAndroid Build Coastguard Worker return;
3291*61046927SAndroid Build Coastguard Worker }
3292*61046927SAndroid Build Coastguard Worker
3293*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
3294*61046927SAndroid Build Coastguard Worker "glGetNamedBufferPointerv");
3295*61046927SAndroid Build Coastguard Worker if (!bufObj)
3296*61046927SAndroid Build Coastguard Worker return;
3297*61046927SAndroid Build Coastguard Worker
3298*61046927SAndroid Build Coastguard Worker *params = bufObj->Mappings[MAP_USER].Pointer;
3299*61046927SAndroid Build Coastguard Worker }
3300*61046927SAndroid Build Coastguard Worker
3301*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetNamedBufferPointervEXT(GLuint buffer,GLenum pname,GLvoid ** params)3302*61046927SAndroid Build Coastguard Worker _mesa_GetNamedBufferPointervEXT(GLuint buffer, GLenum pname, GLvoid **params)
3303*61046927SAndroid Build Coastguard Worker {
3304*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3305*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3306*61046927SAndroid Build Coastguard Worker
3307*61046927SAndroid Build Coastguard Worker if (!buffer) {
3308*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3309*61046927SAndroid Build Coastguard Worker "glGetNamedBufferPointervEXT(buffer=0)");
3310*61046927SAndroid Build Coastguard Worker return;
3311*61046927SAndroid Build Coastguard Worker }
3312*61046927SAndroid Build Coastguard Worker if (pname != GL_BUFFER_MAP_POINTER) {
3313*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glGetNamedBufferPointervEXT(pname != "
3314*61046927SAndroid Build Coastguard Worker "GL_BUFFER_MAP_POINTER)");
3315*61046927SAndroid Build Coastguard Worker return;
3316*61046927SAndroid Build Coastguard Worker }
3317*61046927SAndroid Build Coastguard Worker
3318*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
3319*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
3320*61046927SAndroid Build Coastguard Worker &bufObj, "glGetNamedBufferPointervEXT", false))
3321*61046927SAndroid Build Coastguard Worker return;
3322*61046927SAndroid Build Coastguard Worker
3323*61046927SAndroid Build Coastguard Worker *params = bufObj->Mappings[MAP_USER].Pointer;
3324*61046927SAndroid Build Coastguard Worker }
3325*61046927SAndroid Build Coastguard Worker
3326*61046927SAndroid Build Coastguard Worker static void
copy_buffer_sub_data(struct gl_context * ctx,struct gl_buffer_object * src,struct gl_buffer_object * dst,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size,const char * func)3327*61046927SAndroid Build Coastguard Worker copy_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *src,
3328*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *dst, GLintptr readOffset,
3329*61046927SAndroid Build Coastguard Worker GLintptr writeOffset, GLsizeiptr size, const char *func)
3330*61046927SAndroid Build Coastguard Worker {
3331*61046927SAndroid Build Coastguard Worker if (_mesa_check_disallowed_mapping(src)) {
3332*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3333*61046927SAndroid Build Coastguard Worker "%s(readBuffer is mapped)", func);
3334*61046927SAndroid Build Coastguard Worker return;
3335*61046927SAndroid Build Coastguard Worker }
3336*61046927SAndroid Build Coastguard Worker
3337*61046927SAndroid Build Coastguard Worker if (_mesa_check_disallowed_mapping(dst)) {
3338*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3339*61046927SAndroid Build Coastguard Worker "%s(writeBuffer is mapped)", func);
3340*61046927SAndroid Build Coastguard Worker return;
3341*61046927SAndroid Build Coastguard Worker }
3342*61046927SAndroid Build Coastguard Worker
3343*61046927SAndroid Build Coastguard Worker if (readOffset < 0) {
3344*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3345*61046927SAndroid Build Coastguard Worker "%s(readOffset %d < 0)", func, (int) readOffset);
3346*61046927SAndroid Build Coastguard Worker return;
3347*61046927SAndroid Build Coastguard Worker }
3348*61046927SAndroid Build Coastguard Worker
3349*61046927SAndroid Build Coastguard Worker if (writeOffset < 0) {
3350*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3351*61046927SAndroid Build Coastguard Worker "%s(writeOffset %d < 0)", func, (int) writeOffset);
3352*61046927SAndroid Build Coastguard Worker return;
3353*61046927SAndroid Build Coastguard Worker }
3354*61046927SAndroid Build Coastguard Worker
3355*61046927SAndroid Build Coastguard Worker if (size < 0) {
3356*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3357*61046927SAndroid Build Coastguard Worker "%s(size %d < 0)", func, (int) size);
3358*61046927SAndroid Build Coastguard Worker return;
3359*61046927SAndroid Build Coastguard Worker }
3360*61046927SAndroid Build Coastguard Worker
3361*61046927SAndroid Build Coastguard Worker if (size > src->Size || readOffset > src->Size - size) {
3362*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3363*61046927SAndroid Build Coastguard Worker "%s(readOffset %d + size %d > src_buffer_size %d)", func,
3364*61046927SAndroid Build Coastguard Worker (int) readOffset, (int) size, (int) src->Size);
3365*61046927SAndroid Build Coastguard Worker return;
3366*61046927SAndroid Build Coastguard Worker }
3367*61046927SAndroid Build Coastguard Worker
3368*61046927SAndroid Build Coastguard Worker if (size > dst->Size || writeOffset > dst->Size - size) {
3369*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3370*61046927SAndroid Build Coastguard Worker "%s(writeOffset %d + size %d > dst_buffer_size %d)", func,
3371*61046927SAndroid Build Coastguard Worker (int) writeOffset, (int) size, (int) dst->Size);
3372*61046927SAndroid Build Coastguard Worker return;
3373*61046927SAndroid Build Coastguard Worker }
3374*61046927SAndroid Build Coastguard Worker
3375*61046927SAndroid Build Coastguard Worker if (src == dst) {
3376*61046927SAndroid Build Coastguard Worker if (readOffset + size <= writeOffset) {
3377*61046927SAndroid Build Coastguard Worker /* OK */
3378*61046927SAndroid Build Coastguard Worker }
3379*61046927SAndroid Build Coastguard Worker else if (writeOffset + size <= readOffset) {
3380*61046927SAndroid Build Coastguard Worker /* OK */
3381*61046927SAndroid Build Coastguard Worker }
3382*61046927SAndroid Build Coastguard Worker else {
3383*61046927SAndroid Build Coastguard Worker /* overlapping src/dst is illegal */
3384*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3385*61046927SAndroid Build Coastguard Worker "%s(overlapping src/dst)", func);
3386*61046927SAndroid Build Coastguard Worker return;
3387*61046927SAndroid Build Coastguard Worker }
3388*61046927SAndroid Build Coastguard Worker }
3389*61046927SAndroid Build Coastguard Worker
3390*61046927SAndroid Build Coastguard Worker bufferobj_copy_subdata(ctx, src, dst, readOffset, writeOffset, size);
3391*61046927SAndroid Build Coastguard Worker }
3392*61046927SAndroid Build Coastguard Worker
3393*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyBufferSubData_no_error(GLenum readTarget,GLenum writeTarget,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)3394*61046927SAndroid Build Coastguard Worker _mesa_CopyBufferSubData_no_error(GLenum readTarget, GLenum writeTarget,
3395*61046927SAndroid Build Coastguard Worker GLintptr readOffset, GLintptr writeOffset,
3396*61046927SAndroid Build Coastguard Worker GLsizeiptr size)
3397*61046927SAndroid Build Coastguard Worker {
3398*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3399*61046927SAndroid Build Coastguard Worker
3400*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **src_ptr = get_buffer_target(ctx, readTarget, true);
3401*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *src = *src_ptr;
3402*61046927SAndroid Build Coastguard Worker
3403*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **dst_ptr = get_buffer_target(ctx, writeTarget, true);
3404*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *dst = *dst_ptr;
3405*61046927SAndroid Build Coastguard Worker
3406*61046927SAndroid Build Coastguard Worker bufferobj_copy_subdata(ctx, src, dst, readOffset, writeOffset,
3407*61046927SAndroid Build Coastguard Worker size);
3408*61046927SAndroid Build Coastguard Worker }
3409*61046927SAndroid Build Coastguard Worker
3410*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyBufferSubData(GLenum readTarget,GLenum writeTarget,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)3411*61046927SAndroid Build Coastguard Worker _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
3412*61046927SAndroid Build Coastguard Worker GLintptr readOffset, GLintptr writeOffset,
3413*61046927SAndroid Build Coastguard Worker GLsizeiptr size)
3414*61046927SAndroid Build Coastguard Worker {
3415*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3416*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *src, *dst;
3417*61046927SAndroid Build Coastguard Worker
3418*61046927SAndroid Build Coastguard Worker src = get_buffer(ctx, "glCopyBufferSubData", readTarget,
3419*61046927SAndroid Build Coastguard Worker GL_INVALID_OPERATION);
3420*61046927SAndroid Build Coastguard Worker if (!src)
3421*61046927SAndroid Build Coastguard Worker return;
3422*61046927SAndroid Build Coastguard Worker
3423*61046927SAndroid Build Coastguard Worker dst = get_buffer(ctx, "glCopyBufferSubData", writeTarget,
3424*61046927SAndroid Build Coastguard Worker GL_INVALID_OPERATION);
3425*61046927SAndroid Build Coastguard Worker if (!dst)
3426*61046927SAndroid Build Coastguard Worker return;
3427*61046927SAndroid Build Coastguard Worker
3428*61046927SAndroid Build Coastguard Worker copy_buffer_sub_data(ctx, src, dst, readOffset, writeOffset, size,
3429*61046927SAndroid Build Coastguard Worker "glCopyBufferSubData");
3430*61046927SAndroid Build Coastguard Worker }
3431*61046927SAndroid Build Coastguard Worker
3432*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedCopyBufferSubDataEXT(GLuint readBuffer,GLuint writeBuffer,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)3433*61046927SAndroid Build Coastguard Worker _mesa_NamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer,
3434*61046927SAndroid Build Coastguard Worker GLintptr readOffset, GLintptr writeOffset,
3435*61046927SAndroid Build Coastguard Worker GLsizeiptr size)
3436*61046927SAndroid Build Coastguard Worker {
3437*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3438*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *src, *dst;
3439*61046927SAndroid Build Coastguard Worker
3440*61046927SAndroid Build Coastguard Worker src = _mesa_lookup_bufferobj(ctx, readBuffer);
3441*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, readBuffer,
3442*61046927SAndroid Build Coastguard Worker &src,
3443*61046927SAndroid Build Coastguard Worker "glNamedCopyBufferSubDataEXT", false))
3444*61046927SAndroid Build Coastguard Worker return;
3445*61046927SAndroid Build Coastguard Worker
3446*61046927SAndroid Build Coastguard Worker dst = _mesa_lookup_bufferobj(ctx, writeBuffer);
3447*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, writeBuffer,
3448*61046927SAndroid Build Coastguard Worker &dst, "glNamedCopyBufferSubDataEXT", false))
3449*61046927SAndroid Build Coastguard Worker return;
3450*61046927SAndroid Build Coastguard Worker
3451*61046927SAndroid Build Coastguard Worker copy_buffer_sub_data(ctx, src, dst, readOffset, writeOffset, size,
3452*61046927SAndroid Build Coastguard Worker "glNamedCopyBufferSubDataEXT");
3453*61046927SAndroid Build Coastguard Worker }
3454*61046927SAndroid Build Coastguard Worker
3455*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyNamedBufferSubData_no_error(GLuint readBuffer,GLuint writeBuffer,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)3456*61046927SAndroid Build Coastguard Worker _mesa_CopyNamedBufferSubData_no_error(GLuint readBuffer, GLuint writeBuffer,
3457*61046927SAndroid Build Coastguard Worker GLintptr readOffset,
3458*61046927SAndroid Build Coastguard Worker GLintptr writeOffset, GLsizeiptr size)
3459*61046927SAndroid Build Coastguard Worker {
3460*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3461*61046927SAndroid Build Coastguard Worker
3462*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *src = _mesa_lookup_bufferobj(ctx, readBuffer);
3463*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *dst = _mesa_lookup_bufferobj(ctx, writeBuffer);
3464*61046927SAndroid Build Coastguard Worker
3465*61046927SAndroid Build Coastguard Worker bufferobj_copy_subdata(ctx, src, dst, readOffset, writeOffset,
3466*61046927SAndroid Build Coastguard Worker size);
3467*61046927SAndroid Build Coastguard Worker }
3468*61046927SAndroid Build Coastguard Worker
3469*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_CopyNamedBufferSubData(GLuint readBuffer,GLuint writeBuffer,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)3470*61046927SAndroid Build Coastguard Worker _mesa_CopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer,
3471*61046927SAndroid Build Coastguard Worker GLintptr readOffset, GLintptr writeOffset,
3472*61046927SAndroid Build Coastguard Worker GLsizeiptr size)
3473*61046927SAndroid Build Coastguard Worker {
3474*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3475*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *src, *dst;
3476*61046927SAndroid Build Coastguard Worker
3477*61046927SAndroid Build Coastguard Worker src = _mesa_lookup_bufferobj_err(ctx, readBuffer,
3478*61046927SAndroid Build Coastguard Worker "glCopyNamedBufferSubData");
3479*61046927SAndroid Build Coastguard Worker if (!src)
3480*61046927SAndroid Build Coastguard Worker return;
3481*61046927SAndroid Build Coastguard Worker
3482*61046927SAndroid Build Coastguard Worker dst = _mesa_lookup_bufferobj_err(ctx, writeBuffer,
3483*61046927SAndroid Build Coastguard Worker "glCopyNamedBufferSubData");
3484*61046927SAndroid Build Coastguard Worker if (!dst)
3485*61046927SAndroid Build Coastguard Worker return;
3486*61046927SAndroid Build Coastguard Worker
3487*61046927SAndroid Build Coastguard Worker copy_buffer_sub_data(ctx, src, dst, readOffset, writeOffset, size,
3488*61046927SAndroid Build Coastguard Worker "glCopyNamedBufferSubData");
3489*61046927SAndroid Build Coastguard Worker }
3490*61046927SAndroid Build Coastguard Worker
3491*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InternalBufferSubDataCopyMESA(GLintptr srcBuffer,GLuint srcOffset,GLuint dstTargetOrName,GLintptr dstOffset,GLsizeiptr size,GLboolean named,GLboolean ext_dsa)3492*61046927SAndroid Build Coastguard Worker _mesa_InternalBufferSubDataCopyMESA(GLintptr srcBuffer, GLuint srcOffset,
3493*61046927SAndroid Build Coastguard Worker GLuint dstTargetOrName, GLintptr dstOffset,
3494*61046927SAndroid Build Coastguard Worker GLsizeiptr size, GLboolean named,
3495*61046927SAndroid Build Coastguard Worker GLboolean ext_dsa)
3496*61046927SAndroid Build Coastguard Worker {
3497*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3498*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *src = (struct gl_buffer_object *)srcBuffer;
3499*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *dst;
3500*61046927SAndroid Build Coastguard Worker const char *func;
3501*61046927SAndroid Build Coastguard Worker
3502*61046927SAndroid Build Coastguard Worker /* Handle behavior for all 3 variants. */
3503*61046927SAndroid Build Coastguard Worker if (named && ext_dsa) {
3504*61046927SAndroid Build Coastguard Worker func = "glNamedBufferSubDataEXT";
3505*61046927SAndroid Build Coastguard Worker dst = _mesa_lookup_bufferobj(ctx, dstTargetOrName);
3506*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, dstTargetOrName, &dst, func, false))
3507*61046927SAndroid Build Coastguard Worker goto done;
3508*61046927SAndroid Build Coastguard Worker } else if (named) {
3509*61046927SAndroid Build Coastguard Worker func = "glNamedBufferSubData";
3510*61046927SAndroid Build Coastguard Worker dst = _mesa_lookup_bufferobj_err(ctx, dstTargetOrName, func);
3511*61046927SAndroid Build Coastguard Worker if (!dst)
3512*61046927SAndroid Build Coastguard Worker goto done;
3513*61046927SAndroid Build Coastguard Worker } else {
3514*61046927SAndroid Build Coastguard Worker assert(!ext_dsa);
3515*61046927SAndroid Build Coastguard Worker func = "glBufferSubData";
3516*61046927SAndroid Build Coastguard Worker dst = get_buffer(ctx, func, dstTargetOrName, GL_INVALID_OPERATION);
3517*61046927SAndroid Build Coastguard Worker if (!dst)
3518*61046927SAndroid Build Coastguard Worker goto done;
3519*61046927SAndroid Build Coastguard Worker }
3520*61046927SAndroid Build Coastguard Worker
3521*61046927SAndroid Build Coastguard Worker if (!validate_buffer_sub_data(ctx, dst, dstOffset, size, func))
3522*61046927SAndroid Build Coastguard Worker goto done; /* the error is already set */
3523*61046927SAndroid Build Coastguard Worker
3524*61046927SAndroid Build Coastguard Worker bufferobj_copy_subdata(ctx, src, dst, srcOffset, dstOffset, size);
3525*61046927SAndroid Build Coastguard Worker
3526*61046927SAndroid Build Coastguard Worker done:
3527*61046927SAndroid Build Coastguard Worker /* The caller passes the reference to this function, so unreference it. */
3528*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &src, NULL);
3529*61046927SAndroid Build Coastguard Worker }
3530*61046927SAndroid Build Coastguard Worker
3531*61046927SAndroid Build Coastguard Worker static bool
validate_map_buffer_range(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr length,GLbitfield access,const char * func)3532*61046927SAndroid Build Coastguard Worker validate_map_buffer_range(struct gl_context *ctx,
3533*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj, GLintptr offset,
3534*61046927SAndroid Build Coastguard Worker GLsizeiptr length, GLbitfield access,
3535*61046927SAndroid Build Coastguard Worker const char *func)
3536*61046927SAndroid Build Coastguard Worker {
3537*61046927SAndroid Build Coastguard Worker GLbitfield allowed_access;
3538*61046927SAndroid Build Coastguard Worker
3539*61046927SAndroid Build Coastguard Worker ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, false);
3540*61046927SAndroid Build Coastguard Worker
3541*61046927SAndroid Build Coastguard Worker if (offset < 0) {
3542*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3543*61046927SAndroid Build Coastguard Worker "%s(offset %ld < 0)", func, (long) offset);
3544*61046927SAndroid Build Coastguard Worker return false;
3545*61046927SAndroid Build Coastguard Worker }
3546*61046927SAndroid Build Coastguard Worker
3547*61046927SAndroid Build Coastguard Worker if (length < 0) {
3548*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3549*61046927SAndroid Build Coastguard Worker "%s(length %ld < 0)", func, (long) length);
3550*61046927SAndroid Build Coastguard Worker return false;
3551*61046927SAndroid Build Coastguard Worker }
3552*61046927SAndroid Build Coastguard Worker
3553*61046927SAndroid Build Coastguard Worker /* Page 38 of the PDF of the OpenGL ES 3.0 spec says:
3554*61046927SAndroid Build Coastguard Worker *
3555*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated for any of the following
3556*61046927SAndroid Build Coastguard Worker * conditions:
3557*61046927SAndroid Build Coastguard Worker *
3558*61046927SAndroid Build Coastguard Worker * * <length> is zero."
3559*61046927SAndroid Build Coastguard Worker *
3560*61046927SAndroid Build Coastguard Worker * Additionally, page 94 of the PDF of the OpenGL 4.5 core spec
3561*61046927SAndroid Build Coastguard Worker * (30.10.2014) also says this, so it's no longer allowed for desktop GL,
3562*61046927SAndroid Build Coastguard Worker * either.
3563*61046927SAndroid Build Coastguard Worker */
3564*61046927SAndroid Build Coastguard Worker if (length == 0) {
3565*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(length = 0)", func);
3566*61046927SAndroid Build Coastguard Worker return false;
3567*61046927SAndroid Build Coastguard Worker }
3568*61046927SAndroid Build Coastguard Worker
3569*61046927SAndroid Build Coastguard Worker allowed_access = GL_MAP_READ_BIT |
3570*61046927SAndroid Build Coastguard Worker GL_MAP_WRITE_BIT |
3571*61046927SAndroid Build Coastguard Worker GL_MAP_INVALIDATE_RANGE_BIT |
3572*61046927SAndroid Build Coastguard Worker GL_MAP_INVALIDATE_BUFFER_BIT |
3573*61046927SAndroid Build Coastguard Worker GL_MAP_FLUSH_EXPLICIT_BIT |
3574*61046927SAndroid Build Coastguard Worker GL_MAP_UNSYNCHRONIZED_BIT;
3575*61046927SAndroid Build Coastguard Worker
3576*61046927SAndroid Build Coastguard Worker if (ctx->Extensions.ARB_buffer_storage) {
3577*61046927SAndroid Build Coastguard Worker allowed_access |= GL_MAP_PERSISTENT_BIT |
3578*61046927SAndroid Build Coastguard Worker GL_MAP_COHERENT_BIT;
3579*61046927SAndroid Build Coastguard Worker }
3580*61046927SAndroid Build Coastguard Worker
3581*61046927SAndroid Build Coastguard Worker if (access & ~allowed_access) {
3582*61046927SAndroid Build Coastguard Worker /* generate an error if any bits other than those allowed are set */
3583*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3584*61046927SAndroid Build Coastguard Worker "%s(access has undefined bits set)", func);
3585*61046927SAndroid Build Coastguard Worker return false;
3586*61046927SAndroid Build Coastguard Worker }
3587*61046927SAndroid Build Coastguard Worker
3588*61046927SAndroid Build Coastguard Worker if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) {
3589*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3590*61046927SAndroid Build Coastguard Worker "%s(access indicates neither read or write)", func);
3591*61046927SAndroid Build Coastguard Worker return false;
3592*61046927SAndroid Build Coastguard Worker }
3593*61046927SAndroid Build Coastguard Worker
3594*61046927SAndroid Build Coastguard Worker if ((access & GL_MAP_READ_BIT) &&
3595*61046927SAndroid Build Coastguard Worker (access & (GL_MAP_INVALIDATE_RANGE_BIT |
3596*61046927SAndroid Build Coastguard Worker GL_MAP_INVALIDATE_BUFFER_BIT |
3597*61046927SAndroid Build Coastguard Worker GL_MAP_UNSYNCHRONIZED_BIT))) {
3598*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3599*61046927SAndroid Build Coastguard Worker "%s(read access with disallowed bits)", func);
3600*61046927SAndroid Build Coastguard Worker return false;
3601*61046927SAndroid Build Coastguard Worker }
3602*61046927SAndroid Build Coastguard Worker
3603*61046927SAndroid Build Coastguard Worker if ((access & GL_MAP_FLUSH_EXPLICIT_BIT) &&
3604*61046927SAndroid Build Coastguard Worker ((access & GL_MAP_WRITE_BIT) == 0)) {
3605*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3606*61046927SAndroid Build Coastguard Worker "%s(access has flush explicit without write)", func);
3607*61046927SAndroid Build Coastguard Worker return false;
3608*61046927SAndroid Build Coastguard Worker }
3609*61046927SAndroid Build Coastguard Worker
3610*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_READ_BIT &&
3611*61046927SAndroid Build Coastguard Worker !(bufObj->StorageFlags & GL_MAP_READ_BIT)) {
3612*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3613*61046927SAndroid Build Coastguard Worker "%s(buffer does not allow read access)", func);
3614*61046927SAndroid Build Coastguard Worker return false;
3615*61046927SAndroid Build Coastguard Worker }
3616*61046927SAndroid Build Coastguard Worker
3617*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_WRITE_BIT &&
3618*61046927SAndroid Build Coastguard Worker !(bufObj->StorageFlags & GL_MAP_WRITE_BIT)) {
3619*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3620*61046927SAndroid Build Coastguard Worker "%s(buffer does not allow write access)", func);
3621*61046927SAndroid Build Coastguard Worker return false;
3622*61046927SAndroid Build Coastguard Worker }
3623*61046927SAndroid Build Coastguard Worker
3624*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_COHERENT_BIT &&
3625*61046927SAndroid Build Coastguard Worker !(bufObj->StorageFlags & GL_MAP_COHERENT_BIT)) {
3626*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3627*61046927SAndroid Build Coastguard Worker "%s(buffer does not allow coherent access)", func);
3628*61046927SAndroid Build Coastguard Worker return false;
3629*61046927SAndroid Build Coastguard Worker }
3630*61046927SAndroid Build Coastguard Worker
3631*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_PERSISTENT_BIT &&
3632*61046927SAndroid Build Coastguard Worker !(bufObj->StorageFlags & GL_MAP_PERSISTENT_BIT)) {
3633*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3634*61046927SAndroid Build Coastguard Worker "%s(buffer does not allow persistent access)", func);
3635*61046927SAndroid Build Coastguard Worker return false;
3636*61046927SAndroid Build Coastguard Worker }
3637*61046927SAndroid Build Coastguard Worker
3638*61046927SAndroid Build Coastguard Worker if (offset + length > bufObj->Size) {
3639*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3640*61046927SAndroid Build Coastguard Worker "%s(offset %lu + length %lu > buffer_size %lu)", func,
3641*61046927SAndroid Build Coastguard Worker (unsigned long) offset, (unsigned long) length,
3642*61046927SAndroid Build Coastguard Worker (unsigned long) bufObj->Size);
3643*61046927SAndroid Build Coastguard Worker return false;
3644*61046927SAndroid Build Coastguard Worker }
3645*61046927SAndroid Build Coastguard Worker
3646*61046927SAndroid Build Coastguard Worker if (_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
3647*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3648*61046927SAndroid Build Coastguard Worker "%s(buffer already mapped)", func);
3649*61046927SAndroid Build Coastguard Worker return false;
3650*61046927SAndroid Build Coastguard Worker }
3651*61046927SAndroid Build Coastguard Worker
3652*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_WRITE_BIT) {
3653*61046927SAndroid Build Coastguard Worker bufObj->NumMapBufferWriteCalls++;
3654*61046927SAndroid Build Coastguard Worker if ((bufObj->Usage == GL_STATIC_DRAW ||
3655*61046927SAndroid Build Coastguard Worker bufObj->Usage == GL_STATIC_COPY) &&
3656*61046927SAndroid Build Coastguard Worker bufObj->NumMapBufferWriteCalls >= BUFFER_WARNING_CALL_COUNT) {
3657*61046927SAndroid Build Coastguard Worker BUFFER_USAGE_WARNING(ctx,
3658*61046927SAndroid Build Coastguard Worker "using %s(buffer %u, offset %u, length %u) to "
3659*61046927SAndroid Build Coastguard Worker "update a %s buffer",
3660*61046927SAndroid Build Coastguard Worker func, bufObj->Name, offset, length,
3661*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(bufObj->Usage));
3662*61046927SAndroid Build Coastguard Worker }
3663*61046927SAndroid Build Coastguard Worker }
3664*61046927SAndroid Build Coastguard Worker
3665*61046927SAndroid Build Coastguard Worker return true;
3666*61046927SAndroid Build Coastguard Worker }
3667*61046927SAndroid Build Coastguard Worker
3668*61046927SAndroid Build Coastguard Worker static void *
map_buffer_range(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr length,GLbitfield access,const char * func)3669*61046927SAndroid Build Coastguard Worker map_buffer_range(struct gl_context *ctx, struct gl_buffer_object *bufObj,
3670*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr length, GLbitfield access,
3671*61046927SAndroid Build Coastguard Worker const char *func)
3672*61046927SAndroid Build Coastguard Worker {
3673*61046927SAndroid Build Coastguard Worker if (!bufObj->Size) {
3674*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(buffer size = 0)", func);
3675*61046927SAndroid Build Coastguard Worker return NULL;
3676*61046927SAndroid Build Coastguard Worker }
3677*61046927SAndroid Build Coastguard Worker
3678*61046927SAndroid Build Coastguard Worker void *map = _mesa_bufferobj_map_range(ctx, offset, length, access, bufObj,
3679*61046927SAndroid Build Coastguard Worker MAP_USER);
3680*61046927SAndroid Build Coastguard Worker if (!map) {
3681*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(map failed)", func);
3682*61046927SAndroid Build Coastguard Worker }
3683*61046927SAndroid Build Coastguard Worker else {
3684*61046927SAndroid Build Coastguard Worker /* The driver callback should have set all these fields.
3685*61046927SAndroid Build Coastguard Worker * This is important because other modules (like VBO) might call
3686*61046927SAndroid Build Coastguard Worker * the driver function directly.
3687*61046927SAndroid Build Coastguard Worker */
3688*61046927SAndroid Build Coastguard Worker assert(bufObj->Mappings[MAP_USER].Pointer == map);
3689*61046927SAndroid Build Coastguard Worker assert(bufObj->Mappings[MAP_USER].Length == length);
3690*61046927SAndroid Build Coastguard Worker assert(bufObj->Mappings[MAP_USER].Offset == offset);
3691*61046927SAndroid Build Coastguard Worker assert(bufObj->Mappings[MAP_USER].AccessFlags == access);
3692*61046927SAndroid Build Coastguard Worker }
3693*61046927SAndroid Build Coastguard Worker
3694*61046927SAndroid Build Coastguard Worker if (access & GL_MAP_WRITE_BIT) {
3695*61046927SAndroid Build Coastguard Worker bufObj->MinMaxCacheDirty = true;
3696*61046927SAndroid Build Coastguard Worker }
3697*61046927SAndroid Build Coastguard Worker
3698*61046927SAndroid Build Coastguard Worker #ifdef VBO_DEBUG
3699*61046927SAndroid Build Coastguard Worker if (strstr(func, "Range") == NULL) { /* If not MapRange */
3700*61046927SAndroid Build Coastguard Worker printf("glMapBuffer(%u, sz %ld, access 0x%x)\n",
3701*61046927SAndroid Build Coastguard Worker bufObj->Name, bufObj->Size, access);
3702*61046927SAndroid Build Coastguard Worker /* Access must be write only */
3703*61046927SAndroid Build Coastguard Worker if ((access & GL_MAP_WRITE_BIT) && (!(access & ~GL_MAP_WRITE_BIT))) {
3704*61046927SAndroid Build Coastguard Worker GLuint i;
3705*61046927SAndroid Build Coastguard Worker GLubyte *b = (GLubyte *) bufObj->Mappings[MAP_USER].Pointer;
3706*61046927SAndroid Build Coastguard Worker for (i = 0; i < bufObj->Size; i++)
3707*61046927SAndroid Build Coastguard Worker b[i] = i & 0xff;
3708*61046927SAndroid Build Coastguard Worker }
3709*61046927SAndroid Build Coastguard Worker }
3710*61046927SAndroid Build Coastguard Worker #endif
3711*61046927SAndroid Build Coastguard Worker
3712*61046927SAndroid Build Coastguard Worker #ifdef BOUNDS_CHECK
3713*61046927SAndroid Build Coastguard Worker if (strstr(func, "Range") == NULL) { /* If not MapRange */
3714*61046927SAndroid Build Coastguard Worker GLubyte *buf = (GLubyte *) bufObj->Mappings[MAP_USER].Pointer;
3715*61046927SAndroid Build Coastguard Worker GLuint i;
3716*61046927SAndroid Build Coastguard Worker /* buffer is 100 bytes larger than requested, fill with magic value */
3717*61046927SAndroid Build Coastguard Worker for (i = 0; i < 100; i++) {
3718*61046927SAndroid Build Coastguard Worker buf[bufObj->Size - i - 1] = 123;
3719*61046927SAndroid Build Coastguard Worker }
3720*61046927SAndroid Build Coastguard Worker }
3721*61046927SAndroid Build Coastguard Worker #endif
3722*61046927SAndroid Build Coastguard Worker
3723*61046927SAndroid Build Coastguard Worker return map;
3724*61046927SAndroid Build Coastguard Worker }
3725*61046927SAndroid Build Coastguard Worker
3726*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapBufferRange_no_error(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)3727*61046927SAndroid Build Coastguard Worker _mesa_MapBufferRange_no_error(GLenum target, GLintptr offset,
3728*61046927SAndroid Build Coastguard Worker GLsizeiptr length, GLbitfield access)
3729*61046927SAndroid Build Coastguard Worker {
3730*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3731*61046927SAndroid Build Coastguard Worker
3732*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true);
3733*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = *bufObjPtr;
3734*61046927SAndroid Build Coastguard Worker
3735*61046927SAndroid Build Coastguard Worker return map_buffer_range(ctx, bufObj, offset, length, access,
3736*61046927SAndroid Build Coastguard Worker "glMapBufferRange");
3737*61046927SAndroid Build Coastguard Worker }
3738*61046927SAndroid Build Coastguard Worker
3739*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapBufferRange(GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)3740*61046927SAndroid Build Coastguard Worker _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
3741*61046927SAndroid Build Coastguard Worker GLbitfield access)
3742*61046927SAndroid Build Coastguard Worker {
3743*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3744*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3745*61046927SAndroid Build Coastguard Worker
3746*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_map_buffer_range) {
3747*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3748*61046927SAndroid Build Coastguard Worker "glMapBufferRange(ARB_map_buffer_range not supported)");
3749*61046927SAndroid Build Coastguard Worker return NULL;
3750*61046927SAndroid Build Coastguard Worker }
3751*61046927SAndroid Build Coastguard Worker
3752*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glMapBufferRange", target, GL_INVALID_OPERATION);
3753*61046927SAndroid Build Coastguard Worker if (!bufObj)
3754*61046927SAndroid Build Coastguard Worker return NULL;
3755*61046927SAndroid Build Coastguard Worker
3756*61046927SAndroid Build Coastguard Worker if (!validate_map_buffer_range(ctx, bufObj, offset, length, access,
3757*61046927SAndroid Build Coastguard Worker "glMapBufferRange"))
3758*61046927SAndroid Build Coastguard Worker return NULL;
3759*61046927SAndroid Build Coastguard Worker
3760*61046927SAndroid Build Coastguard Worker return map_buffer_range(ctx, bufObj, offset, length, access,
3761*61046927SAndroid Build Coastguard Worker "glMapBufferRange");
3762*61046927SAndroid Build Coastguard Worker }
3763*61046927SAndroid Build Coastguard Worker
3764*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapNamedBufferRange_no_error(GLuint buffer,GLintptr offset,GLsizeiptr length,GLbitfield access)3765*61046927SAndroid Build Coastguard Worker _mesa_MapNamedBufferRange_no_error(GLuint buffer, GLintptr offset,
3766*61046927SAndroid Build Coastguard Worker GLsizeiptr length, GLbitfield access)
3767*61046927SAndroid Build Coastguard Worker {
3768*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3769*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
3770*61046927SAndroid Build Coastguard Worker
3771*61046927SAndroid Build Coastguard Worker return map_buffer_range(ctx, bufObj, offset, length, access,
3772*61046927SAndroid Build Coastguard Worker "glMapNamedBufferRange");
3773*61046927SAndroid Build Coastguard Worker }
3774*61046927SAndroid Build Coastguard Worker
3775*61046927SAndroid Build Coastguard Worker static void *
map_named_buffer_range(GLuint buffer,GLintptr offset,GLsizeiptr length,GLbitfield access,bool dsa_ext,const char * func)3776*61046927SAndroid Build Coastguard Worker map_named_buffer_range(GLuint buffer, GLintptr offset, GLsizeiptr length,
3777*61046927SAndroid Build Coastguard Worker GLbitfield access, bool dsa_ext, const char *func)
3778*61046927SAndroid Build Coastguard Worker {
3779*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3780*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = NULL;
3781*61046927SAndroid Build Coastguard Worker
3782*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_map_buffer_range) {
3783*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3784*61046927SAndroid Build Coastguard Worker "%s(ARB_map_buffer_range not supported)", func);
3785*61046927SAndroid Build Coastguard Worker return NULL;
3786*61046927SAndroid Build Coastguard Worker }
3787*61046927SAndroid Build Coastguard Worker
3788*61046927SAndroid Build Coastguard Worker if (dsa_ext) {
3789*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
3790*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer, &bufObj, func, false))
3791*61046927SAndroid Build Coastguard Worker return NULL;
3792*61046927SAndroid Build Coastguard Worker } else {
3793*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, func);
3794*61046927SAndroid Build Coastguard Worker if (!bufObj)
3795*61046927SAndroid Build Coastguard Worker return NULL;
3796*61046927SAndroid Build Coastguard Worker }
3797*61046927SAndroid Build Coastguard Worker
3798*61046927SAndroid Build Coastguard Worker if (!validate_map_buffer_range(ctx, bufObj, offset, length, access, func))
3799*61046927SAndroid Build Coastguard Worker return NULL;
3800*61046927SAndroid Build Coastguard Worker
3801*61046927SAndroid Build Coastguard Worker return map_buffer_range(ctx, bufObj, offset, length, access, func);
3802*61046927SAndroid Build Coastguard Worker }
3803*61046927SAndroid Build Coastguard Worker
3804*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapNamedBufferRangeEXT(GLuint buffer,GLintptr offset,GLsizeiptr length,GLbitfield access)3805*61046927SAndroid Build Coastguard Worker _mesa_MapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, GLsizeiptr length,
3806*61046927SAndroid Build Coastguard Worker GLbitfield access)
3807*61046927SAndroid Build Coastguard Worker {
3808*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3809*61046927SAndroid Build Coastguard Worker if (!buffer) {
3810*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3811*61046927SAndroid Build Coastguard Worker "glMapNamedBufferRangeEXT(buffer=0)");
3812*61046927SAndroid Build Coastguard Worker return NULL;
3813*61046927SAndroid Build Coastguard Worker }
3814*61046927SAndroid Build Coastguard Worker return map_named_buffer_range(buffer, offset, length, access, true,
3815*61046927SAndroid Build Coastguard Worker "glMapNamedBufferRangeEXT");
3816*61046927SAndroid Build Coastguard Worker }
3817*61046927SAndroid Build Coastguard Worker
3818*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapNamedBufferRange(GLuint buffer,GLintptr offset,GLsizeiptr length,GLbitfield access)3819*61046927SAndroid Build Coastguard Worker _mesa_MapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length,
3820*61046927SAndroid Build Coastguard Worker GLbitfield access)
3821*61046927SAndroid Build Coastguard Worker {
3822*61046927SAndroid Build Coastguard Worker return map_named_buffer_range(buffer, offset, length, access, false,
3823*61046927SAndroid Build Coastguard Worker "glMapNamedBufferRange");
3824*61046927SAndroid Build Coastguard Worker }
3825*61046927SAndroid Build Coastguard Worker
3826*61046927SAndroid Build Coastguard Worker /**
3827*61046927SAndroid Build Coastguard Worker * Converts GLenum access from MapBuffer and MapNamedBuffer into
3828*61046927SAndroid Build Coastguard Worker * flags for input to map_buffer_range.
3829*61046927SAndroid Build Coastguard Worker *
3830*61046927SAndroid Build Coastguard Worker * \return true if the type of requested access is permissible.
3831*61046927SAndroid Build Coastguard Worker */
3832*61046927SAndroid Build Coastguard Worker static bool
get_map_buffer_access_flags(struct gl_context * ctx,GLenum access,GLbitfield * flags)3833*61046927SAndroid Build Coastguard Worker get_map_buffer_access_flags(struct gl_context *ctx, GLenum access,
3834*61046927SAndroid Build Coastguard Worker GLbitfield *flags)
3835*61046927SAndroid Build Coastguard Worker {
3836*61046927SAndroid Build Coastguard Worker switch (access) {
3837*61046927SAndroid Build Coastguard Worker case GL_READ_ONLY_ARB:
3838*61046927SAndroid Build Coastguard Worker *flags = GL_MAP_READ_BIT;
3839*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx);
3840*61046927SAndroid Build Coastguard Worker case GL_WRITE_ONLY_ARB:
3841*61046927SAndroid Build Coastguard Worker *flags = GL_MAP_WRITE_BIT;
3842*61046927SAndroid Build Coastguard Worker return true;
3843*61046927SAndroid Build Coastguard Worker case GL_READ_WRITE_ARB:
3844*61046927SAndroid Build Coastguard Worker *flags = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
3845*61046927SAndroid Build Coastguard Worker return _mesa_is_desktop_gl(ctx);
3846*61046927SAndroid Build Coastguard Worker default:
3847*61046927SAndroid Build Coastguard Worker *flags = 0;
3848*61046927SAndroid Build Coastguard Worker return false;
3849*61046927SAndroid Build Coastguard Worker }
3850*61046927SAndroid Build Coastguard Worker }
3851*61046927SAndroid Build Coastguard Worker
3852*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapBuffer_no_error(GLenum target,GLenum access)3853*61046927SAndroid Build Coastguard Worker _mesa_MapBuffer_no_error(GLenum target, GLenum access)
3854*61046927SAndroid Build Coastguard Worker {
3855*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3856*61046927SAndroid Build Coastguard Worker
3857*61046927SAndroid Build Coastguard Worker GLbitfield accessFlags;
3858*61046927SAndroid Build Coastguard Worker get_map_buffer_access_flags(ctx, access, &accessFlags);
3859*61046927SAndroid Build Coastguard Worker
3860*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true);
3861*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = *bufObjPtr;
3862*61046927SAndroid Build Coastguard Worker
3863*61046927SAndroid Build Coastguard Worker return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
3864*61046927SAndroid Build Coastguard Worker "glMapBuffer");
3865*61046927SAndroid Build Coastguard Worker }
3866*61046927SAndroid Build Coastguard Worker
3867*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapBuffer(GLenum target,GLenum access)3868*61046927SAndroid Build Coastguard Worker _mesa_MapBuffer(GLenum target, GLenum access)
3869*61046927SAndroid Build Coastguard Worker {
3870*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3871*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3872*61046927SAndroid Build Coastguard Worker GLbitfield accessFlags;
3873*61046927SAndroid Build Coastguard Worker
3874*61046927SAndroid Build Coastguard Worker if (!get_map_buffer_access_flags(ctx, access, &accessFlags)) {
3875*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glMapBuffer(invalid access)");
3876*61046927SAndroid Build Coastguard Worker return NULL;
3877*61046927SAndroid Build Coastguard Worker }
3878*61046927SAndroid Build Coastguard Worker
3879*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glMapBuffer", target, GL_INVALID_OPERATION);
3880*61046927SAndroid Build Coastguard Worker if (!bufObj)
3881*61046927SAndroid Build Coastguard Worker return NULL;
3882*61046927SAndroid Build Coastguard Worker
3883*61046927SAndroid Build Coastguard Worker if (!validate_map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
3884*61046927SAndroid Build Coastguard Worker "glMapBuffer"))
3885*61046927SAndroid Build Coastguard Worker return NULL;
3886*61046927SAndroid Build Coastguard Worker
3887*61046927SAndroid Build Coastguard Worker return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
3888*61046927SAndroid Build Coastguard Worker "glMapBuffer");
3889*61046927SAndroid Build Coastguard Worker }
3890*61046927SAndroid Build Coastguard Worker
3891*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapNamedBuffer_no_error(GLuint buffer,GLenum access)3892*61046927SAndroid Build Coastguard Worker _mesa_MapNamedBuffer_no_error(GLuint buffer, GLenum access)
3893*61046927SAndroid Build Coastguard Worker {
3894*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3895*61046927SAndroid Build Coastguard Worker
3896*61046927SAndroid Build Coastguard Worker GLbitfield accessFlags;
3897*61046927SAndroid Build Coastguard Worker get_map_buffer_access_flags(ctx, access, &accessFlags);
3898*61046927SAndroid Build Coastguard Worker
3899*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
3900*61046927SAndroid Build Coastguard Worker
3901*61046927SAndroid Build Coastguard Worker return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
3902*61046927SAndroid Build Coastguard Worker "glMapNamedBuffer");
3903*61046927SAndroid Build Coastguard Worker }
3904*61046927SAndroid Build Coastguard Worker
3905*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapNamedBuffer(GLuint buffer,GLenum access)3906*61046927SAndroid Build Coastguard Worker _mesa_MapNamedBuffer(GLuint buffer, GLenum access)
3907*61046927SAndroid Build Coastguard Worker {
3908*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3909*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
3910*61046927SAndroid Build Coastguard Worker GLbitfield accessFlags;
3911*61046927SAndroid Build Coastguard Worker
3912*61046927SAndroid Build Coastguard Worker if (!get_map_buffer_access_flags(ctx, access, &accessFlags)) {
3913*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glMapNamedBuffer(invalid access)");
3914*61046927SAndroid Build Coastguard Worker return NULL;
3915*61046927SAndroid Build Coastguard Worker }
3916*61046927SAndroid Build Coastguard Worker
3917*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, "glMapNamedBuffer");
3918*61046927SAndroid Build Coastguard Worker if (!bufObj)
3919*61046927SAndroid Build Coastguard Worker return NULL;
3920*61046927SAndroid Build Coastguard Worker
3921*61046927SAndroid Build Coastguard Worker if (!validate_map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
3922*61046927SAndroid Build Coastguard Worker "glMapNamedBuffer"))
3923*61046927SAndroid Build Coastguard Worker return NULL;
3924*61046927SAndroid Build Coastguard Worker
3925*61046927SAndroid Build Coastguard Worker return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
3926*61046927SAndroid Build Coastguard Worker "glMapNamedBuffer");
3927*61046927SAndroid Build Coastguard Worker }
3928*61046927SAndroid Build Coastguard Worker
3929*61046927SAndroid Build Coastguard Worker void * GLAPIENTRY
_mesa_MapNamedBufferEXT(GLuint buffer,GLenum access)3930*61046927SAndroid Build Coastguard Worker _mesa_MapNamedBufferEXT(GLuint buffer, GLenum access)
3931*61046927SAndroid Build Coastguard Worker {
3932*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
3933*61046927SAndroid Build Coastguard Worker
3934*61046927SAndroid Build Coastguard Worker GLbitfield accessFlags;
3935*61046927SAndroid Build Coastguard Worker if (!buffer) {
3936*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3937*61046927SAndroid Build Coastguard Worker "glMapNamedBufferEXT(buffer=0)");
3938*61046927SAndroid Build Coastguard Worker return NULL;
3939*61046927SAndroid Build Coastguard Worker }
3940*61046927SAndroid Build Coastguard Worker if (!get_map_buffer_access_flags(ctx, access, &accessFlags)) {
3941*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glMapNamedBufferEXT(invalid access)");
3942*61046927SAndroid Build Coastguard Worker return NULL;
3943*61046927SAndroid Build Coastguard Worker }
3944*61046927SAndroid Build Coastguard Worker
3945*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
3946*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
3947*61046927SAndroid Build Coastguard Worker &bufObj, "glMapNamedBufferEXT", false))
3948*61046927SAndroid Build Coastguard Worker return NULL;
3949*61046927SAndroid Build Coastguard Worker
3950*61046927SAndroid Build Coastguard Worker if (!validate_map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
3951*61046927SAndroid Build Coastguard Worker "glMapNamedBufferEXT"))
3952*61046927SAndroid Build Coastguard Worker return NULL;
3953*61046927SAndroid Build Coastguard Worker
3954*61046927SAndroid Build Coastguard Worker return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags,
3955*61046927SAndroid Build Coastguard Worker "glMapNamedBufferEXT");
3956*61046927SAndroid Build Coastguard Worker }
3957*61046927SAndroid Build Coastguard Worker
3958*61046927SAndroid Build Coastguard Worker static void
flush_mapped_buffer_range(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr length,const char * func)3959*61046927SAndroid Build Coastguard Worker flush_mapped_buffer_range(struct gl_context *ctx,
3960*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
3961*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr length,
3962*61046927SAndroid Build Coastguard Worker const char *func)
3963*61046927SAndroid Build Coastguard Worker {
3964*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_map_buffer_range) {
3965*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3966*61046927SAndroid Build Coastguard Worker "%s(ARB_map_buffer_range not supported)", func);
3967*61046927SAndroid Build Coastguard Worker return;
3968*61046927SAndroid Build Coastguard Worker }
3969*61046927SAndroid Build Coastguard Worker
3970*61046927SAndroid Build Coastguard Worker if (offset < 0) {
3971*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3972*61046927SAndroid Build Coastguard Worker "%s(offset %ld < 0)", func, (long) offset);
3973*61046927SAndroid Build Coastguard Worker return;
3974*61046927SAndroid Build Coastguard Worker }
3975*61046927SAndroid Build Coastguard Worker
3976*61046927SAndroid Build Coastguard Worker if (length < 0) {
3977*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3978*61046927SAndroid Build Coastguard Worker "%s(length %ld < 0)", func, (long) length);
3979*61046927SAndroid Build Coastguard Worker return;
3980*61046927SAndroid Build Coastguard Worker }
3981*61046927SAndroid Build Coastguard Worker
3982*61046927SAndroid Build Coastguard Worker if (!_mesa_bufferobj_mapped(bufObj, MAP_USER)) {
3983*61046927SAndroid Build Coastguard Worker /* buffer is not mapped */
3984*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3985*61046927SAndroid Build Coastguard Worker "%s(buffer is not mapped)", func);
3986*61046927SAndroid Build Coastguard Worker return;
3987*61046927SAndroid Build Coastguard Worker }
3988*61046927SAndroid Build Coastguard Worker
3989*61046927SAndroid Build Coastguard Worker if ((bufObj->Mappings[MAP_USER].AccessFlags &
3990*61046927SAndroid Build Coastguard Worker GL_MAP_FLUSH_EXPLICIT_BIT) == 0) {
3991*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
3992*61046927SAndroid Build Coastguard Worker "%s(GL_MAP_FLUSH_EXPLICIT_BIT not set)", func);
3993*61046927SAndroid Build Coastguard Worker return;
3994*61046927SAndroid Build Coastguard Worker }
3995*61046927SAndroid Build Coastguard Worker
3996*61046927SAndroid Build Coastguard Worker if (offset + length > bufObj->Mappings[MAP_USER].Length) {
3997*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
3998*61046927SAndroid Build Coastguard Worker "%s(offset %ld + length %ld > mapped length %ld)", func,
3999*61046927SAndroid Build Coastguard Worker (long) offset, (long) length,
4000*61046927SAndroid Build Coastguard Worker (long) bufObj->Mappings[MAP_USER].Length);
4001*61046927SAndroid Build Coastguard Worker return;
4002*61046927SAndroid Build Coastguard Worker }
4003*61046927SAndroid Build Coastguard Worker
4004*61046927SAndroid Build Coastguard Worker assert(bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_WRITE_BIT);
4005*61046927SAndroid Build Coastguard Worker
4006*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_flush_mapped_range(ctx, offset, length, bufObj,
4007*61046927SAndroid Build Coastguard Worker MAP_USER);
4008*61046927SAndroid Build Coastguard Worker }
4009*61046927SAndroid Build Coastguard Worker
4010*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FlushMappedBufferRange_no_error(GLenum target,GLintptr offset,GLsizeiptr length)4011*61046927SAndroid Build Coastguard Worker _mesa_FlushMappedBufferRange_no_error(GLenum target, GLintptr offset,
4012*61046927SAndroid Build Coastguard Worker GLsizeiptr length)
4013*61046927SAndroid Build Coastguard Worker {
4014*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4015*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true);
4016*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = *bufObjPtr;
4017*61046927SAndroid Build Coastguard Worker
4018*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_flush_mapped_range(ctx, offset, length, bufObj,
4019*61046927SAndroid Build Coastguard Worker MAP_USER);
4020*61046927SAndroid Build Coastguard Worker }
4021*61046927SAndroid Build Coastguard Worker
4022*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FlushMappedBufferRange(GLenum target,GLintptr offset,GLsizeiptr length)4023*61046927SAndroid Build Coastguard Worker _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset,
4024*61046927SAndroid Build Coastguard Worker GLsizeiptr length)
4025*61046927SAndroid Build Coastguard Worker {
4026*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4027*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
4028*61046927SAndroid Build Coastguard Worker
4029*61046927SAndroid Build Coastguard Worker bufObj = get_buffer(ctx, "glFlushMappedBufferRange", target,
4030*61046927SAndroid Build Coastguard Worker GL_INVALID_OPERATION);
4031*61046927SAndroid Build Coastguard Worker if (!bufObj)
4032*61046927SAndroid Build Coastguard Worker return;
4033*61046927SAndroid Build Coastguard Worker
4034*61046927SAndroid Build Coastguard Worker flush_mapped_buffer_range(ctx, bufObj, offset, length,
4035*61046927SAndroid Build Coastguard Worker "glFlushMappedBufferRange");
4036*61046927SAndroid Build Coastguard Worker }
4037*61046927SAndroid Build Coastguard Worker
4038*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FlushMappedNamedBufferRange_no_error(GLuint buffer,GLintptr offset,GLsizeiptr length)4039*61046927SAndroid Build Coastguard Worker _mesa_FlushMappedNamedBufferRange_no_error(GLuint buffer, GLintptr offset,
4040*61046927SAndroid Build Coastguard Worker GLsizeiptr length)
4041*61046927SAndroid Build Coastguard Worker {
4042*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4043*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
4044*61046927SAndroid Build Coastguard Worker
4045*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_flush_mapped_range(ctx, offset, length, bufObj,
4046*61046927SAndroid Build Coastguard Worker MAP_USER);
4047*61046927SAndroid Build Coastguard Worker }
4048*61046927SAndroid Build Coastguard Worker
4049*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FlushMappedNamedBufferRange(GLuint buffer,GLintptr offset,GLsizeiptr length)4050*61046927SAndroid Build Coastguard Worker _mesa_FlushMappedNamedBufferRange(GLuint buffer, GLintptr offset,
4051*61046927SAndroid Build Coastguard Worker GLsizeiptr length)
4052*61046927SAndroid Build Coastguard Worker {
4053*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4054*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
4055*61046927SAndroid Build Coastguard Worker
4056*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj_err(ctx, buffer,
4057*61046927SAndroid Build Coastguard Worker "glFlushMappedNamedBufferRange");
4058*61046927SAndroid Build Coastguard Worker if (!bufObj)
4059*61046927SAndroid Build Coastguard Worker return;
4060*61046927SAndroid Build Coastguard Worker
4061*61046927SAndroid Build Coastguard Worker flush_mapped_buffer_range(ctx, bufObj, offset, length,
4062*61046927SAndroid Build Coastguard Worker "glFlushMappedNamedBufferRange");
4063*61046927SAndroid Build Coastguard Worker }
4064*61046927SAndroid Build Coastguard Worker
4065*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_FlushMappedNamedBufferRangeEXT(GLuint buffer,GLintptr offset,GLsizeiptr length)4066*61046927SAndroid Build Coastguard Worker _mesa_FlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset,
4067*61046927SAndroid Build Coastguard Worker GLsizeiptr length)
4068*61046927SAndroid Build Coastguard Worker {
4069*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4070*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
4071*61046927SAndroid Build Coastguard Worker
4072*61046927SAndroid Build Coastguard Worker if (!buffer) {
4073*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4074*61046927SAndroid Build Coastguard Worker "glFlushMappedNamedBufferRangeEXT(buffer=0)");
4075*61046927SAndroid Build Coastguard Worker return;
4076*61046927SAndroid Build Coastguard Worker }
4077*61046927SAndroid Build Coastguard Worker
4078*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
4079*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
4080*61046927SAndroid Build Coastguard Worker &bufObj, "glFlushMappedNamedBufferRangeEXT", false))
4081*61046927SAndroid Build Coastguard Worker return;
4082*61046927SAndroid Build Coastguard Worker
4083*61046927SAndroid Build Coastguard Worker flush_mapped_buffer_range(ctx, bufObj, offset, length,
4084*61046927SAndroid Build Coastguard Worker "glFlushMappedNamedBufferRangeEXT");
4085*61046927SAndroid Build Coastguard Worker }
4086*61046927SAndroid Build Coastguard Worker
4087*61046927SAndroid Build Coastguard Worker static void
bind_buffer_range_uniform_buffer(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size)4088*61046927SAndroid Build Coastguard Worker bind_buffer_range_uniform_buffer(struct gl_context *ctx, GLuint index,
4089*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
4090*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size)
4091*61046927SAndroid Build Coastguard Worker {
4092*61046927SAndroid Build Coastguard Worker if (!bufObj) {
4093*61046927SAndroid Build Coastguard Worker offset = -1;
4094*61046927SAndroid Build Coastguard Worker size = -1;
4095*61046927SAndroid Build Coastguard Worker }
4096*61046927SAndroid Build Coastguard Worker
4097*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->UniformBuffer, bufObj);
4098*61046927SAndroid Build Coastguard Worker bind_uniform_buffer(ctx, index, bufObj, offset, size, GL_FALSE);
4099*61046927SAndroid Build Coastguard Worker }
4100*61046927SAndroid Build Coastguard Worker
4101*61046927SAndroid Build Coastguard Worker /**
4102*61046927SAndroid Build Coastguard Worker * Bind a region of a buffer object to a uniform block binding point.
4103*61046927SAndroid Build Coastguard Worker * \param index the uniform buffer binding point index
4104*61046927SAndroid Build Coastguard Worker * \param bufObj the buffer object
4105*61046927SAndroid Build Coastguard Worker * \param offset offset to the start of buffer object region
4106*61046927SAndroid Build Coastguard Worker * \param size size of the buffer object region
4107*61046927SAndroid Build Coastguard Worker */
4108*61046927SAndroid Build Coastguard Worker static void
bind_buffer_range_uniform_buffer_err(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size)4109*61046927SAndroid Build Coastguard Worker bind_buffer_range_uniform_buffer_err(struct gl_context *ctx, GLuint index,
4110*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
4111*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size)
4112*61046927SAndroid Build Coastguard Worker {
4113*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.MaxUniformBufferBindings) {
4114*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
4115*61046927SAndroid Build Coastguard Worker return;
4116*61046927SAndroid Build Coastguard Worker }
4117*61046927SAndroid Build Coastguard Worker
4118*61046927SAndroid Build Coastguard Worker if (offset & (ctx->Const.UniformBufferOffsetAlignment - 1)) {
4119*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4120*61046927SAndroid Build Coastguard Worker "glBindBufferRange(offset misaligned %d/%d)", (int) offset,
4121*61046927SAndroid Build Coastguard Worker ctx->Const.UniformBufferOffsetAlignment);
4122*61046927SAndroid Build Coastguard Worker return;
4123*61046927SAndroid Build Coastguard Worker }
4124*61046927SAndroid Build Coastguard Worker
4125*61046927SAndroid Build Coastguard Worker bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
4126*61046927SAndroid Build Coastguard Worker }
4127*61046927SAndroid Build Coastguard Worker
4128*61046927SAndroid Build Coastguard Worker static void
bind_buffer_range_shader_storage_buffer(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size)4129*61046927SAndroid Build Coastguard Worker bind_buffer_range_shader_storage_buffer(struct gl_context *ctx,
4130*61046927SAndroid Build Coastguard Worker GLuint index,
4131*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
4132*61046927SAndroid Build Coastguard Worker GLintptr offset,
4133*61046927SAndroid Build Coastguard Worker GLsizeiptr size)
4134*61046927SAndroid Build Coastguard Worker {
4135*61046927SAndroid Build Coastguard Worker if (!bufObj) {
4136*61046927SAndroid Build Coastguard Worker offset = -1;
4137*61046927SAndroid Build Coastguard Worker size = -1;
4138*61046927SAndroid Build Coastguard Worker }
4139*61046927SAndroid Build Coastguard Worker
4140*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->ShaderStorageBuffer, bufObj);
4141*61046927SAndroid Build Coastguard Worker bind_shader_storage_buffer(ctx, index, bufObj, offset, size, GL_FALSE);
4142*61046927SAndroid Build Coastguard Worker }
4143*61046927SAndroid Build Coastguard Worker
4144*61046927SAndroid Build Coastguard Worker /**
4145*61046927SAndroid Build Coastguard Worker * Bind a region of a buffer object to a shader storage block binding point.
4146*61046927SAndroid Build Coastguard Worker * \param index the shader storage buffer binding point index
4147*61046927SAndroid Build Coastguard Worker * \param bufObj the buffer object
4148*61046927SAndroid Build Coastguard Worker * \param offset offset to the start of buffer object region
4149*61046927SAndroid Build Coastguard Worker * \param size size of the buffer object region
4150*61046927SAndroid Build Coastguard Worker */
4151*61046927SAndroid Build Coastguard Worker static void
bind_buffer_range_shader_storage_buffer_err(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size)4152*61046927SAndroid Build Coastguard Worker bind_buffer_range_shader_storage_buffer_err(struct gl_context *ctx,
4153*61046927SAndroid Build Coastguard Worker GLuint index,
4154*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
4155*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size)
4156*61046927SAndroid Build Coastguard Worker {
4157*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.MaxShaderStorageBufferBindings) {
4158*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
4159*61046927SAndroid Build Coastguard Worker return;
4160*61046927SAndroid Build Coastguard Worker }
4161*61046927SAndroid Build Coastguard Worker
4162*61046927SAndroid Build Coastguard Worker if (offset & (ctx->Const.ShaderStorageBufferOffsetAlignment - 1)) {
4163*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4164*61046927SAndroid Build Coastguard Worker "glBindBufferRange(offset misaligned %d/%d)", (int) offset,
4165*61046927SAndroid Build Coastguard Worker ctx->Const.ShaderStorageBufferOffsetAlignment);
4166*61046927SAndroid Build Coastguard Worker return;
4167*61046927SAndroid Build Coastguard Worker }
4168*61046927SAndroid Build Coastguard Worker
4169*61046927SAndroid Build Coastguard Worker bind_buffer_range_shader_storage_buffer(ctx, index, bufObj, offset, size);
4170*61046927SAndroid Build Coastguard Worker }
4171*61046927SAndroid Build Coastguard Worker
4172*61046927SAndroid Build Coastguard Worker static void
bind_buffer_range_atomic_buffer(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size)4173*61046927SAndroid Build Coastguard Worker bind_buffer_range_atomic_buffer(struct gl_context *ctx, GLuint index,
4174*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
4175*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size)
4176*61046927SAndroid Build Coastguard Worker {
4177*61046927SAndroid Build Coastguard Worker if (!bufObj) {
4178*61046927SAndroid Build Coastguard Worker offset = -1;
4179*61046927SAndroid Build Coastguard Worker size = -1;
4180*61046927SAndroid Build Coastguard Worker }
4181*61046927SAndroid Build Coastguard Worker
4182*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &ctx->AtomicBuffer, bufObj);
4183*61046927SAndroid Build Coastguard Worker bind_atomic_buffer(ctx, index, bufObj, offset, size, GL_FALSE);
4184*61046927SAndroid Build Coastguard Worker }
4185*61046927SAndroid Build Coastguard Worker
4186*61046927SAndroid Build Coastguard Worker /**
4187*61046927SAndroid Build Coastguard Worker * Bind a region of a buffer object to an atomic storage block binding point.
4188*61046927SAndroid Build Coastguard Worker * \param index the shader storage buffer binding point index
4189*61046927SAndroid Build Coastguard Worker * \param bufObj the buffer object
4190*61046927SAndroid Build Coastguard Worker * \param offset offset to the start of buffer object region
4191*61046927SAndroid Build Coastguard Worker * \param size size of the buffer object region
4192*61046927SAndroid Build Coastguard Worker */
4193*61046927SAndroid Build Coastguard Worker static void
bind_buffer_range_atomic_buffer_err(struct gl_context * ctx,GLuint index,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr size)4194*61046927SAndroid Build Coastguard Worker bind_buffer_range_atomic_buffer_err(struct gl_context *ctx,
4195*61046927SAndroid Build Coastguard Worker GLuint index,
4196*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj,
4197*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size)
4198*61046927SAndroid Build Coastguard Worker {
4199*61046927SAndroid Build Coastguard Worker if (index >= ctx->Const.MaxAtomicBufferBindings) {
4200*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(index=%d)", index);
4201*61046927SAndroid Build Coastguard Worker return;
4202*61046927SAndroid Build Coastguard Worker }
4203*61046927SAndroid Build Coastguard Worker
4204*61046927SAndroid Build Coastguard Worker if (offset & (ATOMIC_COUNTER_SIZE - 1)) {
4205*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4206*61046927SAndroid Build Coastguard Worker "glBindBufferRange(offset misaligned %d/%d)", (int) offset,
4207*61046927SAndroid Build Coastguard Worker ATOMIC_COUNTER_SIZE);
4208*61046927SAndroid Build Coastguard Worker return;
4209*61046927SAndroid Build Coastguard Worker }
4210*61046927SAndroid Build Coastguard Worker
4211*61046927SAndroid Build Coastguard Worker bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset, size);
4212*61046927SAndroid Build Coastguard Worker }
4213*61046927SAndroid Build Coastguard Worker
4214*61046927SAndroid Build Coastguard Worker static inline bool
bind_buffers_check_offset_and_size(struct gl_context * ctx,GLuint index,const GLintptr * offsets,const GLsizeiptr * sizes)4215*61046927SAndroid Build Coastguard Worker bind_buffers_check_offset_and_size(struct gl_context *ctx,
4216*61046927SAndroid Build Coastguard Worker GLuint index,
4217*61046927SAndroid Build Coastguard Worker const GLintptr *offsets,
4218*61046927SAndroid Build Coastguard Worker const GLsizeiptr *sizes)
4219*61046927SAndroid Build Coastguard Worker {
4220*61046927SAndroid Build Coastguard Worker if (offsets[index] < 0) {
4221*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4222*61046927SAndroid Build Coastguard Worker *
4223*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated by BindBuffersRange if any
4224*61046927SAndroid Build Coastguard Worker * value in <offsets> is less than zero (per binding)."
4225*61046927SAndroid Build Coastguard Worker */
4226*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4227*61046927SAndroid Build Coastguard Worker "glBindBuffersRange(offsets[%u]=%" PRId64 " < 0)",
4228*61046927SAndroid Build Coastguard Worker index, (int64_t) offsets[index]);
4229*61046927SAndroid Build Coastguard Worker return false;
4230*61046927SAndroid Build Coastguard Worker }
4231*61046927SAndroid Build Coastguard Worker
4232*61046927SAndroid Build Coastguard Worker if (sizes[index] <= 0) {
4233*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4234*61046927SAndroid Build Coastguard Worker *
4235*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated by BindBuffersRange if any
4236*61046927SAndroid Build Coastguard Worker * value in <sizes> is less than or equal to zero (per binding)."
4237*61046927SAndroid Build Coastguard Worker */
4238*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4239*61046927SAndroid Build Coastguard Worker "glBindBuffersRange(sizes[%u]=%" PRId64 " <= 0)",
4240*61046927SAndroid Build Coastguard Worker index, (int64_t) sizes[index]);
4241*61046927SAndroid Build Coastguard Worker return false;
4242*61046927SAndroid Build Coastguard Worker }
4243*61046927SAndroid Build Coastguard Worker
4244*61046927SAndroid Build Coastguard Worker return true;
4245*61046927SAndroid Build Coastguard Worker }
4246*61046927SAndroid Build Coastguard Worker
4247*61046927SAndroid Build Coastguard Worker static bool
error_check_bind_uniform_buffers(struct gl_context * ctx,GLuint first,GLsizei count,const char * caller)4248*61046927SAndroid Build Coastguard Worker error_check_bind_uniform_buffers(struct gl_context *ctx,
4249*61046927SAndroid Build Coastguard Worker GLuint first, GLsizei count,
4250*61046927SAndroid Build Coastguard Worker const char *caller)
4251*61046927SAndroid Build Coastguard Worker {
4252*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_uniform_buffer_object) {
4253*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
4254*61046927SAndroid Build Coastguard Worker "%s(target=GL_UNIFORM_BUFFER)", caller);
4255*61046927SAndroid Build Coastguard Worker return false;
4256*61046927SAndroid Build Coastguard Worker }
4257*61046927SAndroid Build Coastguard Worker
4258*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind_spec says:
4259*61046927SAndroid Build Coastguard Worker *
4260*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if <first> + <count> is
4261*61046927SAndroid Build Coastguard Worker * greater than the number of target-specific indexed binding points,
4262*61046927SAndroid Build Coastguard Worker * as described in section 6.7.1."
4263*61046927SAndroid Build Coastguard Worker */
4264*61046927SAndroid Build Coastguard Worker if (first + count > ctx->Const.MaxUniformBufferBindings) {
4265*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4266*61046927SAndroid Build Coastguard Worker "%s(first=%u + count=%d > the value of "
4267*61046927SAndroid Build Coastguard Worker "GL_MAX_UNIFORM_BUFFER_BINDINGS=%u)",
4268*61046927SAndroid Build Coastguard Worker caller, first, count,
4269*61046927SAndroid Build Coastguard Worker ctx->Const.MaxUniformBufferBindings);
4270*61046927SAndroid Build Coastguard Worker return false;
4271*61046927SAndroid Build Coastguard Worker }
4272*61046927SAndroid Build Coastguard Worker
4273*61046927SAndroid Build Coastguard Worker return true;
4274*61046927SAndroid Build Coastguard Worker }
4275*61046927SAndroid Build Coastguard Worker
4276*61046927SAndroid Build Coastguard Worker static bool
error_check_bind_shader_storage_buffers(struct gl_context * ctx,GLuint first,GLsizei count,const char * caller)4277*61046927SAndroid Build Coastguard Worker error_check_bind_shader_storage_buffers(struct gl_context *ctx,
4278*61046927SAndroid Build Coastguard Worker GLuint first, GLsizei count,
4279*61046927SAndroid Build Coastguard Worker const char *caller)
4280*61046927SAndroid Build Coastguard Worker {
4281*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_shader_storage_buffer_object) {
4282*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
4283*61046927SAndroid Build Coastguard Worker "%s(target=GL_SHADER_STORAGE_BUFFER)", caller);
4284*61046927SAndroid Build Coastguard Worker return false;
4285*61046927SAndroid Build Coastguard Worker }
4286*61046927SAndroid Build Coastguard Worker
4287*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind_spec says:
4288*61046927SAndroid Build Coastguard Worker *
4289*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if <first> + <count> is
4290*61046927SAndroid Build Coastguard Worker * greater than the number of target-specific indexed binding points,
4291*61046927SAndroid Build Coastguard Worker * as described in section 6.7.1."
4292*61046927SAndroid Build Coastguard Worker */
4293*61046927SAndroid Build Coastguard Worker if (first + count > ctx->Const.MaxShaderStorageBufferBindings) {
4294*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4295*61046927SAndroid Build Coastguard Worker "%s(first=%u + count=%d > the value of "
4296*61046927SAndroid Build Coastguard Worker "GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS=%u)",
4297*61046927SAndroid Build Coastguard Worker caller, first, count,
4298*61046927SAndroid Build Coastguard Worker ctx->Const.MaxShaderStorageBufferBindings);
4299*61046927SAndroid Build Coastguard Worker return false;
4300*61046927SAndroid Build Coastguard Worker }
4301*61046927SAndroid Build Coastguard Worker
4302*61046927SAndroid Build Coastguard Worker return true;
4303*61046927SAndroid Build Coastguard Worker }
4304*61046927SAndroid Build Coastguard Worker
4305*61046927SAndroid Build Coastguard Worker /**
4306*61046927SAndroid Build Coastguard Worker * Unbind all uniform buffers in the range
4307*61046927SAndroid Build Coastguard Worker * <first> through <first>+<count>-1
4308*61046927SAndroid Build Coastguard Worker */
4309*61046927SAndroid Build Coastguard Worker static void
unbind_uniform_buffers(struct gl_context * ctx,GLuint first,GLsizei count)4310*61046927SAndroid Build Coastguard Worker unbind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count)
4311*61046927SAndroid Build Coastguard Worker {
4312*61046927SAndroid Build Coastguard Worker for (int i = 0; i < count; i++)
4313*61046927SAndroid Build Coastguard Worker set_buffer_binding(ctx, &ctx->UniformBufferBindings[first + i],
4314*61046927SAndroid Build Coastguard Worker NULL, -1, -1, GL_TRUE, 0);
4315*61046927SAndroid Build Coastguard Worker }
4316*61046927SAndroid Build Coastguard Worker
4317*61046927SAndroid Build Coastguard Worker /**
4318*61046927SAndroid Build Coastguard Worker * Unbind all shader storage buffers in the range
4319*61046927SAndroid Build Coastguard Worker * <first> through <first>+<count>-1
4320*61046927SAndroid Build Coastguard Worker */
4321*61046927SAndroid Build Coastguard Worker static void
unbind_shader_storage_buffers(struct gl_context * ctx,GLuint first,GLsizei count)4322*61046927SAndroid Build Coastguard Worker unbind_shader_storage_buffers(struct gl_context *ctx, GLuint first,
4323*61046927SAndroid Build Coastguard Worker GLsizei count)
4324*61046927SAndroid Build Coastguard Worker {
4325*61046927SAndroid Build Coastguard Worker for (int i = 0; i < count; i++)
4326*61046927SAndroid Build Coastguard Worker set_buffer_binding(ctx, &ctx->ShaderStorageBufferBindings[first + i],
4327*61046927SAndroid Build Coastguard Worker NULL, -1, -1, GL_TRUE, 0);
4328*61046927SAndroid Build Coastguard Worker }
4329*61046927SAndroid Build Coastguard Worker
4330*61046927SAndroid Build Coastguard Worker static void
bind_uniform_buffers(struct gl_context * ctx,GLuint first,GLsizei count,const GLuint * buffers,bool range,const GLintptr * offsets,const GLsizeiptr * sizes,const char * caller)4331*61046927SAndroid Build Coastguard Worker bind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count,
4332*61046927SAndroid Build Coastguard Worker const GLuint *buffers,
4333*61046927SAndroid Build Coastguard Worker bool range,
4334*61046927SAndroid Build Coastguard Worker const GLintptr *offsets, const GLsizeiptr *sizes,
4335*61046927SAndroid Build Coastguard Worker const char *caller)
4336*61046927SAndroid Build Coastguard Worker {
4337*61046927SAndroid Build Coastguard Worker if (!error_check_bind_uniform_buffers(ctx, first, count, caller))
4338*61046927SAndroid Build Coastguard Worker return;
4339*61046927SAndroid Build Coastguard Worker
4340*61046927SAndroid Build Coastguard Worker /* Assume that at least one binding will be changed */
4341*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
4342*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_UNIFORM_BUFFER;
4343*61046927SAndroid Build Coastguard Worker
4344*61046927SAndroid Build Coastguard Worker if (!buffers) {
4345*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4346*61046927SAndroid Build Coastguard Worker *
4347*61046927SAndroid Build Coastguard Worker * "If <buffers> is NULL, all bindings from <first> through
4348*61046927SAndroid Build Coastguard Worker * <first>+<count>-1 are reset to their unbound (zero) state.
4349*61046927SAndroid Build Coastguard Worker * In this case, the offsets and sizes associated with the
4350*61046927SAndroid Build Coastguard Worker * binding points are set to default values, ignoring
4351*61046927SAndroid Build Coastguard Worker * <offsets> and <sizes>."
4352*61046927SAndroid Build Coastguard Worker */
4353*61046927SAndroid Build Coastguard Worker unbind_uniform_buffers(ctx, first, count);
4354*61046927SAndroid Build Coastguard Worker return;
4355*61046927SAndroid Build Coastguard Worker }
4356*61046927SAndroid Build Coastguard Worker
4357*61046927SAndroid Build Coastguard Worker /* Note that the error semantics for multi-bind commands differ from
4358*61046927SAndroid Build Coastguard Worker * those of other GL commands.
4359*61046927SAndroid Build Coastguard Worker *
4360*61046927SAndroid Build Coastguard Worker * The Issues section in the ARB_multi_bind spec says:
4361*61046927SAndroid Build Coastguard Worker *
4362*61046927SAndroid Build Coastguard Worker * "(11) Typically, OpenGL specifies that if an error is generated by a
4363*61046927SAndroid Build Coastguard Worker * command, that command has no effect. This is somewhat
4364*61046927SAndroid Build Coastguard Worker * unfortunate for multi-bind commands, because it would require a
4365*61046927SAndroid Build Coastguard Worker * first pass to scan the entire list of bound objects for errors
4366*61046927SAndroid Build Coastguard Worker * and then a second pass to actually perform the bindings.
4367*61046927SAndroid Build Coastguard Worker * Should we have different error semantics?
4368*61046927SAndroid Build Coastguard Worker *
4369*61046927SAndroid Build Coastguard Worker * RESOLVED: Yes. In this specification, when the parameters for
4370*61046927SAndroid Build Coastguard Worker * one of the <count> binding points are invalid, that binding point
4371*61046927SAndroid Build Coastguard Worker * is not updated and an error will be generated. However, other
4372*61046927SAndroid Build Coastguard Worker * binding points in the same command will be updated if their
4373*61046927SAndroid Build Coastguard Worker * parameters are valid and no other error occurs."
4374*61046927SAndroid Build Coastguard Worker */
4375*61046927SAndroid Build Coastguard Worker
4376*61046927SAndroid Build Coastguard Worker _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects,
4377*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
4378*61046927SAndroid Build Coastguard Worker
4379*61046927SAndroid Build Coastguard Worker for (int i = 0; i < count; i++) {
4380*61046927SAndroid Build Coastguard Worker struct gl_buffer_binding *binding =
4381*61046927SAndroid Build Coastguard Worker &ctx->UniformBufferBindings[first + i];
4382*61046927SAndroid Build Coastguard Worker GLintptr offset = 0;
4383*61046927SAndroid Build Coastguard Worker GLsizeiptr size = 0;
4384*61046927SAndroid Build Coastguard Worker
4385*61046927SAndroid Build Coastguard Worker if (range) {
4386*61046927SAndroid Build Coastguard Worker if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes))
4387*61046927SAndroid Build Coastguard Worker continue;
4388*61046927SAndroid Build Coastguard Worker
4389*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4390*61046927SAndroid Build Coastguard Worker *
4391*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated by BindBuffersRange if any
4392*61046927SAndroid Build Coastguard Worker * pair of values in <offsets> and <sizes> does not respectively
4393*61046927SAndroid Build Coastguard Worker * satisfy the constraints described for those parameters for the
4394*61046927SAndroid Build Coastguard Worker * specified target, as described in section 6.7.1 (per binding)."
4395*61046927SAndroid Build Coastguard Worker *
4396*61046927SAndroid Build Coastguard Worker * Section 6.7.1 refers to table 6.5, which says:
4397*61046927SAndroid Build Coastguard Worker *
4398*61046927SAndroid Build Coastguard Worker * "┌───────────────────────────────────────────────────────────────┐
4399*61046927SAndroid Build Coastguard Worker * │ Uniform buffer array bindings (see sec. 7.6) │
4400*61046927SAndroid Build Coastguard Worker * ├─────────────────────┬─────────────────────────────────────────┤
4401*61046927SAndroid Build Coastguard Worker * │ ... │ ... │
4402*61046927SAndroid Build Coastguard Worker * │ offset restriction │ multiple of value of UNIFORM_BUFFER_- │
4403*61046927SAndroid Build Coastguard Worker * │ │ OFFSET_ALIGNMENT │
4404*61046927SAndroid Build Coastguard Worker * │ ... │ ... │
4405*61046927SAndroid Build Coastguard Worker * │ size restriction │ none │
4406*61046927SAndroid Build Coastguard Worker * └─────────────────────┴─────────────────────────────────────────┘"
4407*61046927SAndroid Build Coastguard Worker */
4408*61046927SAndroid Build Coastguard Worker if (offsets[i] & (ctx->Const.UniformBufferOffsetAlignment - 1)) {
4409*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4410*61046927SAndroid Build Coastguard Worker "glBindBuffersRange(offsets[%u]=%" PRId64
4411*61046927SAndroid Build Coastguard Worker " is misaligned; it must be a multiple of the value of "
4412*61046927SAndroid Build Coastguard Worker "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT=%u when "
4413*61046927SAndroid Build Coastguard Worker "target=GL_UNIFORM_BUFFER)",
4414*61046927SAndroid Build Coastguard Worker i, (int64_t) offsets[i],
4415*61046927SAndroid Build Coastguard Worker ctx->Const.UniformBufferOffsetAlignment);
4416*61046927SAndroid Build Coastguard Worker continue;
4417*61046927SAndroid Build Coastguard Worker }
4418*61046927SAndroid Build Coastguard Worker
4419*61046927SAndroid Build Coastguard Worker offset = offsets[i];
4420*61046927SAndroid Build Coastguard Worker size = sizes[i];
4421*61046927SAndroid Build Coastguard Worker }
4422*61046927SAndroid Build Coastguard Worker
4423*61046927SAndroid Build Coastguard Worker set_buffer_multi_binding(ctx, buffers, i, caller,
4424*61046927SAndroid Build Coastguard Worker binding, offset, size, range,
4425*61046927SAndroid Build Coastguard Worker USAGE_UNIFORM_BUFFER);
4426*61046927SAndroid Build Coastguard Worker }
4427*61046927SAndroid Build Coastguard Worker
4428*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects,
4429*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
4430*61046927SAndroid Build Coastguard Worker }
4431*61046927SAndroid Build Coastguard Worker
4432*61046927SAndroid Build Coastguard Worker static void
bind_shader_storage_buffers(struct gl_context * ctx,GLuint first,GLsizei count,const GLuint * buffers,bool range,const GLintptr * offsets,const GLsizeiptr * sizes,const char * caller)4433*61046927SAndroid Build Coastguard Worker bind_shader_storage_buffers(struct gl_context *ctx, GLuint first,
4434*61046927SAndroid Build Coastguard Worker GLsizei count, const GLuint *buffers,
4435*61046927SAndroid Build Coastguard Worker bool range,
4436*61046927SAndroid Build Coastguard Worker const GLintptr *offsets,
4437*61046927SAndroid Build Coastguard Worker const GLsizeiptr *sizes,
4438*61046927SAndroid Build Coastguard Worker const char *caller)
4439*61046927SAndroid Build Coastguard Worker {
4440*61046927SAndroid Build Coastguard Worker if (!error_check_bind_shader_storage_buffers(ctx, first, count, caller))
4441*61046927SAndroid Build Coastguard Worker return;
4442*61046927SAndroid Build Coastguard Worker
4443*61046927SAndroid Build Coastguard Worker /* Assume that at least one binding will be changed */
4444*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
4445*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ST_NEW_STORAGE_BUFFER;
4446*61046927SAndroid Build Coastguard Worker
4447*61046927SAndroid Build Coastguard Worker if (!buffers) {
4448*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4449*61046927SAndroid Build Coastguard Worker *
4450*61046927SAndroid Build Coastguard Worker * "If <buffers> is NULL, all bindings from <first> through
4451*61046927SAndroid Build Coastguard Worker * <first>+<count>-1 are reset to their unbound (zero) state.
4452*61046927SAndroid Build Coastguard Worker * In this case, the offsets and sizes associated with the
4453*61046927SAndroid Build Coastguard Worker * binding points are set to default values, ignoring
4454*61046927SAndroid Build Coastguard Worker * <offsets> and <sizes>."
4455*61046927SAndroid Build Coastguard Worker */
4456*61046927SAndroid Build Coastguard Worker unbind_shader_storage_buffers(ctx, first, count);
4457*61046927SAndroid Build Coastguard Worker return;
4458*61046927SAndroid Build Coastguard Worker }
4459*61046927SAndroid Build Coastguard Worker
4460*61046927SAndroid Build Coastguard Worker /* Note that the error semantics for multi-bind commands differ from
4461*61046927SAndroid Build Coastguard Worker * those of other GL commands.
4462*61046927SAndroid Build Coastguard Worker *
4463*61046927SAndroid Build Coastguard Worker * The Issues section in the ARB_multi_bind spec says:
4464*61046927SAndroid Build Coastguard Worker *
4465*61046927SAndroid Build Coastguard Worker * "(11) Typically, OpenGL specifies that if an error is generated by a
4466*61046927SAndroid Build Coastguard Worker * command, that command has no effect. This is somewhat
4467*61046927SAndroid Build Coastguard Worker * unfortunate for multi-bind commands, because it would require a
4468*61046927SAndroid Build Coastguard Worker * first pass to scan the entire list of bound objects for errors
4469*61046927SAndroid Build Coastguard Worker * and then a second pass to actually perform the bindings.
4470*61046927SAndroid Build Coastguard Worker * Should we have different error semantics?
4471*61046927SAndroid Build Coastguard Worker *
4472*61046927SAndroid Build Coastguard Worker * RESOLVED: Yes. In this specification, when the parameters for
4473*61046927SAndroid Build Coastguard Worker * one of the <count> binding points are invalid, that binding point
4474*61046927SAndroid Build Coastguard Worker * is not updated and an error will be generated. However, other
4475*61046927SAndroid Build Coastguard Worker * binding points in the same command will be updated if their
4476*61046927SAndroid Build Coastguard Worker * parameters are valid and no other error occurs."
4477*61046927SAndroid Build Coastguard Worker */
4478*61046927SAndroid Build Coastguard Worker
4479*61046927SAndroid Build Coastguard Worker _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects,
4480*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
4481*61046927SAndroid Build Coastguard Worker
4482*61046927SAndroid Build Coastguard Worker for (int i = 0; i < count; i++) {
4483*61046927SAndroid Build Coastguard Worker struct gl_buffer_binding *binding =
4484*61046927SAndroid Build Coastguard Worker &ctx->ShaderStorageBufferBindings[first + i];
4485*61046927SAndroid Build Coastguard Worker GLintptr offset = 0;
4486*61046927SAndroid Build Coastguard Worker GLsizeiptr size = 0;
4487*61046927SAndroid Build Coastguard Worker
4488*61046927SAndroid Build Coastguard Worker if (range) {
4489*61046927SAndroid Build Coastguard Worker if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes))
4490*61046927SAndroid Build Coastguard Worker continue;
4491*61046927SAndroid Build Coastguard Worker
4492*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4493*61046927SAndroid Build Coastguard Worker *
4494*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated by BindBuffersRange if any
4495*61046927SAndroid Build Coastguard Worker * pair of values in <offsets> and <sizes> does not respectively
4496*61046927SAndroid Build Coastguard Worker * satisfy the constraints described for those parameters for the
4497*61046927SAndroid Build Coastguard Worker * specified target, as described in section 6.7.1 (per binding)."
4498*61046927SAndroid Build Coastguard Worker *
4499*61046927SAndroid Build Coastguard Worker * Section 6.7.1 refers to table 6.5, which says:
4500*61046927SAndroid Build Coastguard Worker *
4501*61046927SAndroid Build Coastguard Worker * "┌───────────────────────────────────────────────────────────────┐
4502*61046927SAndroid Build Coastguard Worker * │ Shader storage buffer array bindings (see sec. 7.8) │
4503*61046927SAndroid Build Coastguard Worker * ├─────────────────────┬─────────────────────────────────────────┤
4504*61046927SAndroid Build Coastguard Worker * │ ... │ ... │
4505*61046927SAndroid Build Coastguard Worker * │ offset restriction │ multiple of value of SHADER_STORAGE_- │
4506*61046927SAndroid Build Coastguard Worker * │ │ BUFFER_OFFSET_ALIGNMENT │
4507*61046927SAndroid Build Coastguard Worker * │ ... │ ... │
4508*61046927SAndroid Build Coastguard Worker * │ size restriction │ none │
4509*61046927SAndroid Build Coastguard Worker * └─────────────────────┴─────────────────────────────────────────┘"
4510*61046927SAndroid Build Coastguard Worker */
4511*61046927SAndroid Build Coastguard Worker if (offsets[i] & (ctx->Const.ShaderStorageBufferOffsetAlignment - 1)) {
4512*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4513*61046927SAndroid Build Coastguard Worker "glBindBuffersRange(offsets[%u]=%" PRId64
4514*61046927SAndroid Build Coastguard Worker " is misaligned; it must be a multiple of the value of "
4515*61046927SAndroid Build Coastguard Worker "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT=%u when "
4516*61046927SAndroid Build Coastguard Worker "target=GL_SHADER_STORAGE_BUFFER)",
4517*61046927SAndroid Build Coastguard Worker i, (int64_t) offsets[i],
4518*61046927SAndroid Build Coastguard Worker ctx->Const.ShaderStorageBufferOffsetAlignment);
4519*61046927SAndroid Build Coastguard Worker continue;
4520*61046927SAndroid Build Coastguard Worker }
4521*61046927SAndroid Build Coastguard Worker
4522*61046927SAndroid Build Coastguard Worker offset = offsets[i];
4523*61046927SAndroid Build Coastguard Worker size = sizes[i];
4524*61046927SAndroid Build Coastguard Worker }
4525*61046927SAndroid Build Coastguard Worker
4526*61046927SAndroid Build Coastguard Worker set_buffer_multi_binding(ctx, buffers, i, caller,
4527*61046927SAndroid Build Coastguard Worker binding, offset, size, range,
4528*61046927SAndroid Build Coastguard Worker USAGE_SHADER_STORAGE_BUFFER);
4529*61046927SAndroid Build Coastguard Worker }
4530*61046927SAndroid Build Coastguard Worker
4531*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects,
4532*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
4533*61046927SAndroid Build Coastguard Worker }
4534*61046927SAndroid Build Coastguard Worker
4535*61046927SAndroid Build Coastguard Worker static bool
error_check_bind_xfb_buffers(struct gl_context * ctx,struct gl_transform_feedback_object * tfObj,GLuint first,GLsizei count,const char * caller)4536*61046927SAndroid Build Coastguard Worker error_check_bind_xfb_buffers(struct gl_context *ctx,
4537*61046927SAndroid Build Coastguard Worker struct gl_transform_feedback_object *tfObj,
4538*61046927SAndroid Build Coastguard Worker GLuint first, GLsizei count, const char *caller)
4539*61046927SAndroid Build Coastguard Worker {
4540*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.EXT_transform_feedback) {
4541*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
4542*61046927SAndroid Build Coastguard Worker "%s(target=GL_TRANSFORM_FEEDBACK_BUFFER)", caller);
4543*61046927SAndroid Build Coastguard Worker return false;
4544*61046927SAndroid Build Coastguard Worker }
4545*61046927SAndroid Build Coastguard Worker
4546*61046927SAndroid Build Coastguard Worker /* Page 398 of the PDF of the OpenGL 4.4 (Core Profile) spec says:
4547*61046927SAndroid Build Coastguard Worker *
4548*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated :
4549*61046927SAndroid Build Coastguard Worker *
4550*61046927SAndroid Build Coastguard Worker * ...
4551*61046927SAndroid Build Coastguard Worker * • by BindBufferRange or BindBufferBase if target is TRANSFORM_-
4552*61046927SAndroid Build Coastguard Worker * FEEDBACK_BUFFER and transform feedback is currently active."
4553*61046927SAndroid Build Coastguard Worker *
4554*61046927SAndroid Build Coastguard Worker * We assume that this is also meant to apply to BindBuffersRange
4555*61046927SAndroid Build Coastguard Worker * and BindBuffersBase.
4556*61046927SAndroid Build Coastguard Worker */
4557*61046927SAndroid Build Coastguard Worker if (tfObj->Active) {
4558*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4559*61046927SAndroid Build Coastguard Worker "%s(Changing transform feedback buffers while "
4560*61046927SAndroid Build Coastguard Worker "transform feedback is active)", caller);
4561*61046927SAndroid Build Coastguard Worker return false;
4562*61046927SAndroid Build Coastguard Worker }
4563*61046927SAndroid Build Coastguard Worker
4564*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind_spec says:
4565*61046927SAndroid Build Coastguard Worker *
4566*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if <first> + <count> is
4567*61046927SAndroid Build Coastguard Worker * greater than the number of target-specific indexed binding points,
4568*61046927SAndroid Build Coastguard Worker * as described in section 6.7.1."
4569*61046927SAndroid Build Coastguard Worker */
4570*61046927SAndroid Build Coastguard Worker if (first + count > ctx->Const.MaxTransformFeedbackBuffers) {
4571*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4572*61046927SAndroid Build Coastguard Worker "%s(first=%u + count=%d > the value of "
4573*61046927SAndroid Build Coastguard Worker "GL_MAX_TRANSFORM_FEEDBACK_BUFFERS=%u)",
4574*61046927SAndroid Build Coastguard Worker caller, first, count,
4575*61046927SAndroid Build Coastguard Worker ctx->Const.MaxTransformFeedbackBuffers);
4576*61046927SAndroid Build Coastguard Worker return false;
4577*61046927SAndroid Build Coastguard Worker }
4578*61046927SAndroid Build Coastguard Worker
4579*61046927SAndroid Build Coastguard Worker return true;
4580*61046927SAndroid Build Coastguard Worker }
4581*61046927SAndroid Build Coastguard Worker
4582*61046927SAndroid Build Coastguard Worker /**
4583*61046927SAndroid Build Coastguard Worker * Unbind all transform feedback buffers in the range
4584*61046927SAndroid Build Coastguard Worker * <first> through <first>+<count>-1
4585*61046927SAndroid Build Coastguard Worker */
4586*61046927SAndroid Build Coastguard Worker static void
unbind_xfb_buffers(struct gl_context * ctx,struct gl_transform_feedback_object * tfObj,GLuint first,GLsizei count)4587*61046927SAndroid Build Coastguard Worker unbind_xfb_buffers(struct gl_context *ctx,
4588*61046927SAndroid Build Coastguard Worker struct gl_transform_feedback_object *tfObj,
4589*61046927SAndroid Build Coastguard Worker GLuint first, GLsizei count)
4590*61046927SAndroid Build Coastguard Worker {
4591*61046927SAndroid Build Coastguard Worker for (int i = 0; i < count; i++)
4592*61046927SAndroid Build Coastguard Worker _mesa_set_transform_feedback_binding(ctx, tfObj, first + i,
4593*61046927SAndroid Build Coastguard Worker NULL, 0, 0);
4594*61046927SAndroid Build Coastguard Worker }
4595*61046927SAndroid Build Coastguard Worker
4596*61046927SAndroid Build Coastguard Worker static void
bind_xfb_buffers(struct gl_context * ctx,GLuint first,GLsizei count,const GLuint * buffers,bool range,const GLintptr * offsets,const GLsizeiptr * sizes,const char * caller)4597*61046927SAndroid Build Coastguard Worker bind_xfb_buffers(struct gl_context *ctx,
4598*61046927SAndroid Build Coastguard Worker GLuint first, GLsizei count,
4599*61046927SAndroid Build Coastguard Worker const GLuint *buffers,
4600*61046927SAndroid Build Coastguard Worker bool range,
4601*61046927SAndroid Build Coastguard Worker const GLintptr *offsets,
4602*61046927SAndroid Build Coastguard Worker const GLsizeiptr *sizes,
4603*61046927SAndroid Build Coastguard Worker const char *caller)
4604*61046927SAndroid Build Coastguard Worker {
4605*61046927SAndroid Build Coastguard Worker struct gl_transform_feedback_object *tfObj =
4606*61046927SAndroid Build Coastguard Worker ctx->TransformFeedback.CurrentObject;
4607*61046927SAndroid Build Coastguard Worker
4608*61046927SAndroid Build Coastguard Worker if (!error_check_bind_xfb_buffers(ctx, tfObj, first, count, caller))
4609*61046927SAndroid Build Coastguard Worker return;
4610*61046927SAndroid Build Coastguard Worker
4611*61046927SAndroid Build Coastguard Worker /* Assume that at least one binding will be changed */
4612*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
4613*61046927SAndroid Build Coastguard Worker
4614*61046927SAndroid Build Coastguard Worker if (!buffers) {
4615*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4616*61046927SAndroid Build Coastguard Worker *
4617*61046927SAndroid Build Coastguard Worker * "If <buffers> is NULL, all bindings from <first> through
4618*61046927SAndroid Build Coastguard Worker * <first>+<count>-1 are reset to their unbound (zero) state.
4619*61046927SAndroid Build Coastguard Worker * In this case, the offsets and sizes associated with the
4620*61046927SAndroid Build Coastguard Worker * binding points are set to default values, ignoring
4621*61046927SAndroid Build Coastguard Worker * <offsets> and <sizes>."
4622*61046927SAndroid Build Coastguard Worker */
4623*61046927SAndroid Build Coastguard Worker unbind_xfb_buffers(ctx, tfObj, first, count);
4624*61046927SAndroid Build Coastguard Worker return;
4625*61046927SAndroid Build Coastguard Worker }
4626*61046927SAndroid Build Coastguard Worker
4627*61046927SAndroid Build Coastguard Worker /* Note that the error semantics for multi-bind commands differ from
4628*61046927SAndroid Build Coastguard Worker * those of other GL commands.
4629*61046927SAndroid Build Coastguard Worker *
4630*61046927SAndroid Build Coastguard Worker * The Issues section in the ARB_multi_bind spec says:
4631*61046927SAndroid Build Coastguard Worker *
4632*61046927SAndroid Build Coastguard Worker * "(11) Typically, OpenGL specifies that if an error is generated by a
4633*61046927SAndroid Build Coastguard Worker * command, that command has no effect. This is somewhat
4634*61046927SAndroid Build Coastguard Worker * unfortunate for multi-bind commands, because it would require a
4635*61046927SAndroid Build Coastguard Worker * first pass to scan the entire list of bound objects for errors
4636*61046927SAndroid Build Coastguard Worker * and then a second pass to actually perform the bindings.
4637*61046927SAndroid Build Coastguard Worker * Should we have different error semantics?
4638*61046927SAndroid Build Coastguard Worker *
4639*61046927SAndroid Build Coastguard Worker * RESOLVED: Yes. In this specification, when the parameters for
4640*61046927SAndroid Build Coastguard Worker * one of the <count> binding points are invalid, that binding point
4641*61046927SAndroid Build Coastguard Worker * is not updated and an error will be generated. However, other
4642*61046927SAndroid Build Coastguard Worker * binding points in the same command will be updated if their
4643*61046927SAndroid Build Coastguard Worker * parameters are valid and no other error occurs."
4644*61046927SAndroid Build Coastguard Worker */
4645*61046927SAndroid Build Coastguard Worker
4646*61046927SAndroid Build Coastguard Worker _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects,
4647*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
4648*61046927SAndroid Build Coastguard Worker
4649*61046927SAndroid Build Coastguard Worker for (int i = 0; i < count; i++) {
4650*61046927SAndroid Build Coastguard Worker const GLuint index = first + i;
4651*61046927SAndroid Build Coastguard Worker struct gl_buffer_object * const boundBufObj = tfObj->Buffers[index];
4652*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
4653*61046927SAndroid Build Coastguard Worker GLintptr offset = 0;
4654*61046927SAndroid Build Coastguard Worker GLsizeiptr size = 0;
4655*61046927SAndroid Build Coastguard Worker
4656*61046927SAndroid Build Coastguard Worker if (range) {
4657*61046927SAndroid Build Coastguard Worker if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes))
4658*61046927SAndroid Build Coastguard Worker continue;
4659*61046927SAndroid Build Coastguard Worker
4660*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4661*61046927SAndroid Build Coastguard Worker *
4662*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated by BindBuffersRange if any
4663*61046927SAndroid Build Coastguard Worker * pair of values in <offsets> and <sizes> does not respectively
4664*61046927SAndroid Build Coastguard Worker * satisfy the constraints described for those parameters for the
4665*61046927SAndroid Build Coastguard Worker * specified target, as described in section 6.7.1 (per binding)."
4666*61046927SAndroid Build Coastguard Worker *
4667*61046927SAndroid Build Coastguard Worker * Section 6.7.1 refers to table 6.5, which says:
4668*61046927SAndroid Build Coastguard Worker *
4669*61046927SAndroid Build Coastguard Worker * "┌───────────────────────────────────────────────────────────────┐
4670*61046927SAndroid Build Coastguard Worker * │ Transform feedback array bindings (see sec. 13.2.2) │
4671*61046927SAndroid Build Coastguard Worker * ├───────────────────────┬───────────────────────────────────────┤
4672*61046927SAndroid Build Coastguard Worker * │ ... │ ... │
4673*61046927SAndroid Build Coastguard Worker * │ offset restriction │ multiple of 4 │
4674*61046927SAndroid Build Coastguard Worker * │ ... │ ... │
4675*61046927SAndroid Build Coastguard Worker * │ size restriction │ multiple of 4 │
4676*61046927SAndroid Build Coastguard Worker * └───────────────────────┴───────────────────────────────────────┘"
4677*61046927SAndroid Build Coastguard Worker */
4678*61046927SAndroid Build Coastguard Worker if (offsets[i] & 0x3) {
4679*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4680*61046927SAndroid Build Coastguard Worker "glBindBuffersRange(offsets[%u]=%" PRId64
4681*61046927SAndroid Build Coastguard Worker " is misaligned; it must be a multiple of 4 when "
4682*61046927SAndroid Build Coastguard Worker "target=GL_TRANSFORM_FEEDBACK_BUFFER)",
4683*61046927SAndroid Build Coastguard Worker i, (int64_t) offsets[i]);
4684*61046927SAndroid Build Coastguard Worker continue;
4685*61046927SAndroid Build Coastguard Worker }
4686*61046927SAndroid Build Coastguard Worker
4687*61046927SAndroid Build Coastguard Worker if (sizes[i] & 0x3) {
4688*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4689*61046927SAndroid Build Coastguard Worker "glBindBuffersRange(sizes[%u]=%" PRId64
4690*61046927SAndroid Build Coastguard Worker " is misaligned; it must be a multiple of 4 when "
4691*61046927SAndroid Build Coastguard Worker "target=GL_TRANSFORM_FEEDBACK_BUFFER)",
4692*61046927SAndroid Build Coastguard Worker i, (int64_t) sizes[i]);
4693*61046927SAndroid Build Coastguard Worker continue;
4694*61046927SAndroid Build Coastguard Worker }
4695*61046927SAndroid Build Coastguard Worker
4696*61046927SAndroid Build Coastguard Worker offset = offsets[i];
4697*61046927SAndroid Build Coastguard Worker size = sizes[i];
4698*61046927SAndroid Build Coastguard Worker }
4699*61046927SAndroid Build Coastguard Worker
4700*61046927SAndroid Build Coastguard Worker if (boundBufObj && boundBufObj->Name == buffers[i])
4701*61046927SAndroid Build Coastguard Worker bufObj = boundBufObj;
4702*61046927SAndroid Build Coastguard Worker else {
4703*61046927SAndroid Build Coastguard Worker bool error;
4704*61046927SAndroid Build Coastguard Worker bufObj = _mesa_multi_bind_lookup_bufferobj(ctx, buffers, i, caller,
4705*61046927SAndroid Build Coastguard Worker &error);
4706*61046927SAndroid Build Coastguard Worker if (error)
4707*61046927SAndroid Build Coastguard Worker continue;
4708*61046927SAndroid Build Coastguard Worker }
4709*61046927SAndroid Build Coastguard Worker
4710*61046927SAndroid Build Coastguard Worker _mesa_set_transform_feedback_binding(ctx, tfObj, index, bufObj,
4711*61046927SAndroid Build Coastguard Worker offset, size);
4712*61046927SAndroid Build Coastguard Worker }
4713*61046927SAndroid Build Coastguard Worker
4714*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects,
4715*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
4716*61046927SAndroid Build Coastguard Worker }
4717*61046927SAndroid Build Coastguard Worker
4718*61046927SAndroid Build Coastguard Worker static bool
error_check_bind_atomic_buffers(struct gl_context * ctx,GLuint first,GLsizei count,const char * caller)4719*61046927SAndroid Build Coastguard Worker error_check_bind_atomic_buffers(struct gl_context *ctx,
4720*61046927SAndroid Build Coastguard Worker GLuint first, GLsizei count,
4721*61046927SAndroid Build Coastguard Worker const char *caller)
4722*61046927SAndroid Build Coastguard Worker {
4723*61046927SAndroid Build Coastguard Worker if (!ctx->Extensions.ARB_shader_atomic_counters) {
4724*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM,
4725*61046927SAndroid Build Coastguard Worker "%s(target=GL_ATOMIC_COUNTER_BUFFER)", caller);
4726*61046927SAndroid Build Coastguard Worker return false;
4727*61046927SAndroid Build Coastguard Worker }
4728*61046927SAndroid Build Coastguard Worker
4729*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind_spec says:
4730*61046927SAndroid Build Coastguard Worker *
4731*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if <first> + <count> is
4732*61046927SAndroid Build Coastguard Worker * greater than the number of target-specific indexed binding points,
4733*61046927SAndroid Build Coastguard Worker * as described in section 6.7.1."
4734*61046927SAndroid Build Coastguard Worker */
4735*61046927SAndroid Build Coastguard Worker if (first + count > ctx->Const.MaxAtomicBufferBindings) {
4736*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
4737*61046927SAndroid Build Coastguard Worker "%s(first=%u + count=%d > the value of "
4738*61046927SAndroid Build Coastguard Worker "GL_MAX_ATOMIC_BUFFER_BINDINGS=%u)",
4739*61046927SAndroid Build Coastguard Worker caller, first, count, ctx->Const.MaxAtomicBufferBindings);
4740*61046927SAndroid Build Coastguard Worker return false;
4741*61046927SAndroid Build Coastguard Worker }
4742*61046927SAndroid Build Coastguard Worker
4743*61046927SAndroid Build Coastguard Worker return true;
4744*61046927SAndroid Build Coastguard Worker }
4745*61046927SAndroid Build Coastguard Worker
4746*61046927SAndroid Build Coastguard Worker /**
4747*61046927SAndroid Build Coastguard Worker * Unbind all atomic counter buffers in the range
4748*61046927SAndroid Build Coastguard Worker * <first> through <first>+<count>-1
4749*61046927SAndroid Build Coastguard Worker */
4750*61046927SAndroid Build Coastguard Worker static void
unbind_atomic_buffers(struct gl_context * ctx,GLuint first,GLsizei count)4751*61046927SAndroid Build Coastguard Worker unbind_atomic_buffers(struct gl_context *ctx, GLuint first, GLsizei count)
4752*61046927SAndroid Build Coastguard Worker {
4753*61046927SAndroid Build Coastguard Worker for (int i = 0; i < count; i++)
4754*61046927SAndroid Build Coastguard Worker set_buffer_binding(ctx, &ctx->AtomicBufferBindings[first + i],
4755*61046927SAndroid Build Coastguard Worker NULL, -1, -1, GL_TRUE, 0);
4756*61046927SAndroid Build Coastguard Worker }
4757*61046927SAndroid Build Coastguard Worker
4758*61046927SAndroid Build Coastguard Worker static void
bind_atomic_buffers(struct gl_context * ctx,GLuint first,GLsizei count,const GLuint * buffers,bool range,const GLintptr * offsets,const GLsizeiptr * sizes,const char * caller)4759*61046927SAndroid Build Coastguard Worker bind_atomic_buffers(struct gl_context *ctx,
4760*61046927SAndroid Build Coastguard Worker GLuint first,
4761*61046927SAndroid Build Coastguard Worker GLsizei count,
4762*61046927SAndroid Build Coastguard Worker const GLuint *buffers,
4763*61046927SAndroid Build Coastguard Worker bool range,
4764*61046927SAndroid Build Coastguard Worker const GLintptr *offsets,
4765*61046927SAndroid Build Coastguard Worker const GLsizeiptr *sizes,
4766*61046927SAndroid Build Coastguard Worker const char *caller)
4767*61046927SAndroid Build Coastguard Worker {
4768*61046927SAndroid Build Coastguard Worker if (!error_check_bind_atomic_buffers(ctx, first, count, caller))
4769*61046927SAndroid Build Coastguard Worker return;
4770*61046927SAndroid Build Coastguard Worker
4771*61046927SAndroid Build Coastguard Worker /* Assume that at least one binding will be changed */
4772*61046927SAndroid Build Coastguard Worker FLUSH_VERTICES(ctx, 0, 0);
4773*61046927SAndroid Build Coastguard Worker ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer;
4774*61046927SAndroid Build Coastguard Worker
4775*61046927SAndroid Build Coastguard Worker if (!buffers) {
4776*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4777*61046927SAndroid Build Coastguard Worker *
4778*61046927SAndroid Build Coastguard Worker * "If <buffers> is NULL, all bindings from <first> through
4779*61046927SAndroid Build Coastguard Worker * <first>+<count>-1 are reset to their unbound (zero) state.
4780*61046927SAndroid Build Coastguard Worker * In this case, the offsets and sizes associated with the
4781*61046927SAndroid Build Coastguard Worker * binding points are set to default values, ignoring
4782*61046927SAndroid Build Coastguard Worker * <offsets> and <sizes>."
4783*61046927SAndroid Build Coastguard Worker */
4784*61046927SAndroid Build Coastguard Worker unbind_atomic_buffers(ctx, first, count);
4785*61046927SAndroid Build Coastguard Worker return;
4786*61046927SAndroid Build Coastguard Worker }
4787*61046927SAndroid Build Coastguard Worker
4788*61046927SAndroid Build Coastguard Worker /* Note that the error semantics for multi-bind commands differ from
4789*61046927SAndroid Build Coastguard Worker * those of other GL commands.
4790*61046927SAndroid Build Coastguard Worker *
4791*61046927SAndroid Build Coastguard Worker * The Issues section in the ARB_multi_bind spec says:
4792*61046927SAndroid Build Coastguard Worker *
4793*61046927SAndroid Build Coastguard Worker * "(11) Typically, OpenGL specifies that if an error is generated by a
4794*61046927SAndroid Build Coastguard Worker * command, that command has no effect. This is somewhat
4795*61046927SAndroid Build Coastguard Worker * unfortunate for multi-bind commands, because it would require a
4796*61046927SAndroid Build Coastguard Worker * first pass to scan the entire list of bound objects for errors
4797*61046927SAndroid Build Coastguard Worker * and then a second pass to actually perform the bindings.
4798*61046927SAndroid Build Coastguard Worker * Should we have different error semantics?
4799*61046927SAndroid Build Coastguard Worker *
4800*61046927SAndroid Build Coastguard Worker * RESOLVED: Yes. In this specification, when the parameters for
4801*61046927SAndroid Build Coastguard Worker * one of the <count> binding points are invalid, that binding point
4802*61046927SAndroid Build Coastguard Worker * is not updated and an error will be generated. However, other
4803*61046927SAndroid Build Coastguard Worker * binding points in the same command will be updated if their
4804*61046927SAndroid Build Coastguard Worker * parameters are valid and no other error occurs."
4805*61046927SAndroid Build Coastguard Worker */
4806*61046927SAndroid Build Coastguard Worker
4807*61046927SAndroid Build Coastguard Worker _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects,
4808*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
4809*61046927SAndroid Build Coastguard Worker
4810*61046927SAndroid Build Coastguard Worker for (int i = 0; i < count; i++) {
4811*61046927SAndroid Build Coastguard Worker struct gl_buffer_binding *binding =
4812*61046927SAndroid Build Coastguard Worker &ctx->AtomicBufferBindings[first + i];
4813*61046927SAndroid Build Coastguard Worker GLintptr offset = 0;
4814*61046927SAndroid Build Coastguard Worker GLsizeiptr size = 0;
4815*61046927SAndroid Build Coastguard Worker
4816*61046927SAndroid Build Coastguard Worker if (range) {
4817*61046927SAndroid Build Coastguard Worker if (!bind_buffers_check_offset_and_size(ctx, i, offsets, sizes))
4818*61046927SAndroid Build Coastguard Worker continue;
4819*61046927SAndroid Build Coastguard Worker
4820*61046927SAndroid Build Coastguard Worker /* The ARB_multi_bind spec says:
4821*61046927SAndroid Build Coastguard Worker *
4822*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated by BindBuffersRange if any
4823*61046927SAndroid Build Coastguard Worker * pair of values in <offsets> and <sizes> does not respectively
4824*61046927SAndroid Build Coastguard Worker * satisfy the constraints described for those parameters for the
4825*61046927SAndroid Build Coastguard Worker * specified target, as described in section 6.7.1 (per binding)."
4826*61046927SAndroid Build Coastguard Worker *
4827*61046927SAndroid Build Coastguard Worker * Section 6.7.1 refers to table 6.5, which says:
4828*61046927SAndroid Build Coastguard Worker *
4829*61046927SAndroid Build Coastguard Worker * "┌───────────────────────────────────────────────────────────────┐
4830*61046927SAndroid Build Coastguard Worker * │ Atomic counter array bindings (see sec. 7.7.2) │
4831*61046927SAndroid Build Coastguard Worker * ├───────────────────────┬───────────────────────────────────────┤
4832*61046927SAndroid Build Coastguard Worker * │ ... │ ... │
4833*61046927SAndroid Build Coastguard Worker * │ offset restriction │ multiple of 4 │
4834*61046927SAndroid Build Coastguard Worker * │ ... │ ... │
4835*61046927SAndroid Build Coastguard Worker * │ size restriction │ none │
4836*61046927SAndroid Build Coastguard Worker * └───────────────────────┴───────────────────────────────────────┘"
4837*61046927SAndroid Build Coastguard Worker */
4838*61046927SAndroid Build Coastguard Worker if (offsets[i] & (ATOMIC_COUNTER_SIZE - 1)) {
4839*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
4840*61046927SAndroid Build Coastguard Worker "glBindBuffersRange(offsets[%u]=%" PRId64
4841*61046927SAndroid Build Coastguard Worker " is misaligned; it must be a multiple of %d when "
4842*61046927SAndroid Build Coastguard Worker "target=GL_ATOMIC_COUNTER_BUFFER)",
4843*61046927SAndroid Build Coastguard Worker i, (int64_t) offsets[i], ATOMIC_COUNTER_SIZE);
4844*61046927SAndroid Build Coastguard Worker continue;
4845*61046927SAndroid Build Coastguard Worker }
4846*61046927SAndroid Build Coastguard Worker
4847*61046927SAndroid Build Coastguard Worker offset = offsets[i];
4848*61046927SAndroid Build Coastguard Worker size = sizes[i];
4849*61046927SAndroid Build Coastguard Worker }
4850*61046927SAndroid Build Coastguard Worker
4851*61046927SAndroid Build Coastguard Worker set_buffer_multi_binding(ctx, buffers, i, caller,
4852*61046927SAndroid Build Coastguard Worker binding, offset, size, range,
4853*61046927SAndroid Build Coastguard Worker USAGE_ATOMIC_COUNTER_BUFFER);
4854*61046927SAndroid Build Coastguard Worker }
4855*61046927SAndroid Build Coastguard Worker
4856*61046927SAndroid Build Coastguard Worker _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects,
4857*61046927SAndroid Build Coastguard Worker ctx->BufferObjectsLocked);
4858*61046927SAndroid Build Coastguard Worker }
4859*61046927SAndroid Build Coastguard Worker
4860*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
bind_buffer_range(GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size,bool no_error)4861*61046927SAndroid Build Coastguard Worker bind_buffer_range(GLenum target, GLuint index, GLuint buffer, GLintptr offset,
4862*61046927SAndroid Build Coastguard Worker GLsizeiptr size, bool no_error)
4863*61046927SAndroid Build Coastguard Worker {
4864*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4865*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
4866*61046927SAndroid Build Coastguard Worker
4867*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API) {
4868*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glBindBufferRange(%s, %u, %u, %lu, %lu)\n",
4869*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target), index, buffer,
4870*61046927SAndroid Build Coastguard Worker (unsigned long) offset, (unsigned long) size);
4871*61046927SAndroid Build Coastguard Worker }
4872*61046927SAndroid Build Coastguard Worker
4873*61046927SAndroid Build Coastguard Worker if (buffer == 0) {
4874*61046927SAndroid Build Coastguard Worker bufObj = NULL;
4875*61046927SAndroid Build Coastguard Worker } else {
4876*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
4877*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
4878*61046927SAndroid Build Coastguard Worker &bufObj, "glBindBufferRange", no_error))
4879*61046927SAndroid Build Coastguard Worker return;
4880*61046927SAndroid Build Coastguard Worker }
4881*61046927SAndroid Build Coastguard Worker
4882*61046927SAndroid Build Coastguard Worker if (no_error) {
4883*61046927SAndroid Build Coastguard Worker switch (target) {
4884*61046927SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_BUFFER:
4885*61046927SAndroid Build Coastguard Worker _mesa_bind_buffer_range_xfb(ctx, ctx->TransformFeedback.CurrentObject,
4886*61046927SAndroid Build Coastguard Worker index, bufObj, offset, size);
4887*61046927SAndroid Build Coastguard Worker return;
4888*61046927SAndroid Build Coastguard Worker case GL_UNIFORM_BUFFER:
4889*61046927SAndroid Build Coastguard Worker bind_buffer_range_uniform_buffer(ctx, index, bufObj, offset, size);
4890*61046927SAndroid Build Coastguard Worker return;
4891*61046927SAndroid Build Coastguard Worker case GL_SHADER_STORAGE_BUFFER:
4892*61046927SAndroid Build Coastguard Worker bind_buffer_range_shader_storage_buffer(ctx, index, bufObj, offset,
4893*61046927SAndroid Build Coastguard Worker size);
4894*61046927SAndroid Build Coastguard Worker return;
4895*61046927SAndroid Build Coastguard Worker case GL_ATOMIC_COUNTER_BUFFER:
4896*61046927SAndroid Build Coastguard Worker bind_buffer_range_atomic_buffer(ctx, index, bufObj, offset, size);
4897*61046927SAndroid Build Coastguard Worker return;
4898*61046927SAndroid Build Coastguard Worker default:
4899*61046927SAndroid Build Coastguard Worker unreachable("invalid BindBufferRange target with KHR_no_error");
4900*61046927SAndroid Build Coastguard Worker }
4901*61046927SAndroid Build Coastguard Worker } else {
4902*61046927SAndroid Build Coastguard Worker if (buffer != 0) {
4903*61046927SAndroid Build Coastguard Worker if (size <= 0) {
4904*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "glBindBufferRange(size=%d)",
4905*61046927SAndroid Build Coastguard Worker (int) size);
4906*61046927SAndroid Build Coastguard Worker return;
4907*61046927SAndroid Build Coastguard Worker }
4908*61046927SAndroid Build Coastguard Worker }
4909*61046927SAndroid Build Coastguard Worker
4910*61046927SAndroid Build Coastguard Worker switch (target) {
4911*61046927SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_BUFFER:
4912*61046927SAndroid Build Coastguard Worker if (!_mesa_validate_buffer_range_xfb(ctx,
4913*61046927SAndroid Build Coastguard Worker ctx->TransformFeedback.CurrentObject,
4914*61046927SAndroid Build Coastguard Worker index, bufObj, offset, size,
4915*61046927SAndroid Build Coastguard Worker false))
4916*61046927SAndroid Build Coastguard Worker return;
4917*61046927SAndroid Build Coastguard Worker
4918*61046927SAndroid Build Coastguard Worker _mesa_bind_buffer_range_xfb(ctx, ctx->TransformFeedback.CurrentObject,
4919*61046927SAndroid Build Coastguard Worker index, bufObj, offset, size);
4920*61046927SAndroid Build Coastguard Worker return;
4921*61046927SAndroid Build Coastguard Worker case GL_UNIFORM_BUFFER:
4922*61046927SAndroid Build Coastguard Worker bind_buffer_range_uniform_buffer_err(ctx, index, bufObj, offset,
4923*61046927SAndroid Build Coastguard Worker size);
4924*61046927SAndroid Build Coastguard Worker return;
4925*61046927SAndroid Build Coastguard Worker case GL_SHADER_STORAGE_BUFFER:
4926*61046927SAndroid Build Coastguard Worker bind_buffer_range_shader_storage_buffer_err(ctx, index, bufObj,
4927*61046927SAndroid Build Coastguard Worker offset, size);
4928*61046927SAndroid Build Coastguard Worker return;
4929*61046927SAndroid Build Coastguard Worker case GL_ATOMIC_COUNTER_BUFFER:
4930*61046927SAndroid Build Coastguard Worker bind_buffer_range_atomic_buffer_err(ctx, index, bufObj,
4931*61046927SAndroid Build Coastguard Worker offset, size);
4932*61046927SAndroid Build Coastguard Worker return;
4933*61046927SAndroid Build Coastguard Worker default:
4934*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferRange(target)");
4935*61046927SAndroid Build Coastguard Worker return;
4936*61046927SAndroid Build Coastguard Worker }
4937*61046927SAndroid Build Coastguard Worker }
4938*61046927SAndroid Build Coastguard Worker }
4939*61046927SAndroid Build Coastguard Worker
4940*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindBufferRange_no_error(GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size)4941*61046927SAndroid Build Coastguard Worker _mesa_BindBufferRange_no_error(GLenum target, GLuint index, GLuint buffer,
4942*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size)
4943*61046927SAndroid Build Coastguard Worker {
4944*61046927SAndroid Build Coastguard Worker bind_buffer_range(target, index, buffer, offset, size, true);
4945*61046927SAndroid Build Coastguard Worker }
4946*61046927SAndroid Build Coastguard Worker
4947*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindBufferRange(GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size)4948*61046927SAndroid Build Coastguard Worker _mesa_BindBufferRange(GLenum target, GLuint index,
4949*61046927SAndroid Build Coastguard Worker GLuint buffer, GLintptr offset, GLsizeiptr size)
4950*61046927SAndroid Build Coastguard Worker {
4951*61046927SAndroid Build Coastguard Worker bind_buffer_range(target, index, buffer, offset, size, false);
4952*61046927SAndroid Build Coastguard Worker }
4953*61046927SAndroid Build Coastguard Worker
4954*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindBufferBase(GLenum target,GLuint index,GLuint buffer)4955*61046927SAndroid Build Coastguard Worker _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer)
4956*61046927SAndroid Build Coastguard Worker {
4957*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
4958*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
4959*61046927SAndroid Build Coastguard Worker
4960*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API) {
4961*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glBindBufferBase(%s, %u, %u)\n",
4962*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target), index, buffer);
4963*61046927SAndroid Build Coastguard Worker }
4964*61046927SAndroid Build Coastguard Worker
4965*61046927SAndroid Build Coastguard Worker if (buffer == 0) {
4966*61046927SAndroid Build Coastguard Worker bufObj = NULL;
4967*61046927SAndroid Build Coastguard Worker } else {
4968*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
4969*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer,
4970*61046927SAndroid Build Coastguard Worker &bufObj, "glBindBufferBase", false))
4971*61046927SAndroid Build Coastguard Worker return;
4972*61046927SAndroid Build Coastguard Worker }
4973*61046927SAndroid Build Coastguard Worker
4974*61046927SAndroid Build Coastguard Worker /* Note that there's some oddness in the GL 3.1-GL 3.3 specifications with
4975*61046927SAndroid Build Coastguard Worker * regards to BindBufferBase. It says (GL 3.1 core spec, page 63):
4976*61046927SAndroid Build Coastguard Worker *
4977*61046927SAndroid Build Coastguard Worker * "BindBufferBase is equivalent to calling BindBufferRange with offset
4978*61046927SAndroid Build Coastguard Worker * zero and size equal to the size of buffer."
4979*61046927SAndroid Build Coastguard Worker *
4980*61046927SAndroid Build Coastguard Worker * but it says for glGetIntegeri_v (GL 3.1 core spec, page 230):
4981*61046927SAndroid Build Coastguard Worker *
4982*61046927SAndroid Build Coastguard Worker * "If the parameter (starting offset or size) was not specified when the
4983*61046927SAndroid Build Coastguard Worker * buffer object was bound, zero is returned."
4984*61046927SAndroid Build Coastguard Worker *
4985*61046927SAndroid Build Coastguard Worker * What happens if the size of the buffer changes? Does the size of the
4986*61046927SAndroid Build Coastguard Worker * buffer at the moment glBindBufferBase was called still play a role, like
4987*61046927SAndroid Build Coastguard Worker * the first quote would imply, or is the size meaningless in the
4988*61046927SAndroid Build Coastguard Worker * glBindBufferBase case like the second quote would suggest? The GL 4.1
4989*61046927SAndroid Build Coastguard Worker * core spec page 45 says:
4990*61046927SAndroid Build Coastguard Worker *
4991*61046927SAndroid Build Coastguard Worker * "It is equivalent to calling BindBufferRange with offset zero, while
4992*61046927SAndroid Build Coastguard Worker * size is determined by the size of the bound buffer at the time the
4993*61046927SAndroid Build Coastguard Worker * binding is used."
4994*61046927SAndroid Build Coastguard Worker *
4995*61046927SAndroid Build Coastguard Worker * My interpretation is that the GL 4.1 spec was a clarification of the
4996*61046927SAndroid Build Coastguard Worker * behavior, not a change. In particular, this choice will only make
4997*61046927SAndroid Build Coastguard Worker * rendering work in cases where it would have had undefined results.
4998*61046927SAndroid Build Coastguard Worker */
4999*61046927SAndroid Build Coastguard Worker
5000*61046927SAndroid Build Coastguard Worker switch (target) {
5001*61046927SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_BUFFER:
5002*61046927SAndroid Build Coastguard Worker _mesa_bind_buffer_base_transform_feedback(ctx,
5003*61046927SAndroid Build Coastguard Worker ctx->TransformFeedback.CurrentObject,
5004*61046927SAndroid Build Coastguard Worker index, bufObj, false);
5005*61046927SAndroid Build Coastguard Worker return;
5006*61046927SAndroid Build Coastguard Worker case GL_UNIFORM_BUFFER:
5007*61046927SAndroid Build Coastguard Worker bind_buffer_base_uniform_buffer(ctx, index, bufObj);
5008*61046927SAndroid Build Coastguard Worker return;
5009*61046927SAndroid Build Coastguard Worker case GL_SHADER_STORAGE_BUFFER:
5010*61046927SAndroid Build Coastguard Worker bind_buffer_base_shader_storage_buffer(ctx, index, bufObj);
5011*61046927SAndroid Build Coastguard Worker return;
5012*61046927SAndroid Build Coastguard Worker case GL_ATOMIC_COUNTER_BUFFER:
5013*61046927SAndroid Build Coastguard Worker bind_buffer_base_atomic_buffer(ctx, index, bufObj);
5014*61046927SAndroid Build Coastguard Worker return;
5015*61046927SAndroid Build Coastguard Worker default:
5016*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferBase(target)");
5017*61046927SAndroid Build Coastguard Worker return;
5018*61046927SAndroid Build Coastguard Worker }
5019*61046927SAndroid Build Coastguard Worker }
5020*61046927SAndroid Build Coastguard Worker
5021*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindBuffersRange(GLenum target,GLuint first,GLsizei count,const GLuint * buffers,const GLintptr * offsets,const GLsizeiptr * sizes)5022*61046927SAndroid Build Coastguard Worker _mesa_BindBuffersRange(GLenum target, GLuint first, GLsizei count,
5023*61046927SAndroid Build Coastguard Worker const GLuint *buffers,
5024*61046927SAndroid Build Coastguard Worker const GLintptr *offsets, const GLsizeiptr *sizes)
5025*61046927SAndroid Build Coastguard Worker {
5026*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5027*61046927SAndroid Build Coastguard Worker
5028*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API) {
5029*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glBindBuffersRange(%s, %u, %d, %p, %p, %p)\n",
5030*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target), first, count,
5031*61046927SAndroid Build Coastguard Worker buffers, offsets, sizes);
5032*61046927SAndroid Build Coastguard Worker }
5033*61046927SAndroid Build Coastguard Worker
5034*61046927SAndroid Build Coastguard Worker switch (target) {
5035*61046927SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_BUFFER:
5036*61046927SAndroid Build Coastguard Worker bind_xfb_buffers(ctx, first, count, buffers, true, offsets, sizes,
5037*61046927SAndroid Build Coastguard Worker "glBindBuffersRange");
5038*61046927SAndroid Build Coastguard Worker return;
5039*61046927SAndroid Build Coastguard Worker case GL_UNIFORM_BUFFER:
5040*61046927SAndroid Build Coastguard Worker bind_uniform_buffers(ctx, first, count, buffers, true, offsets, sizes,
5041*61046927SAndroid Build Coastguard Worker "glBindBuffersRange");
5042*61046927SAndroid Build Coastguard Worker return;
5043*61046927SAndroid Build Coastguard Worker case GL_SHADER_STORAGE_BUFFER:
5044*61046927SAndroid Build Coastguard Worker bind_shader_storage_buffers(ctx, first, count, buffers, true, offsets, sizes,
5045*61046927SAndroid Build Coastguard Worker "glBindBuffersRange");
5046*61046927SAndroid Build Coastguard Worker return;
5047*61046927SAndroid Build Coastguard Worker case GL_ATOMIC_COUNTER_BUFFER:
5048*61046927SAndroid Build Coastguard Worker bind_atomic_buffers(ctx, first, count, buffers, true, offsets, sizes,
5049*61046927SAndroid Build Coastguard Worker "glBindBuffersRange");
5050*61046927SAndroid Build Coastguard Worker return;
5051*61046927SAndroid Build Coastguard Worker default:
5052*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glBindBuffersRange(target=%s)",
5053*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
5054*61046927SAndroid Build Coastguard Worker break;
5055*61046927SAndroid Build Coastguard Worker }
5056*61046927SAndroid Build Coastguard Worker }
5057*61046927SAndroid Build Coastguard Worker
5058*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BindBuffersBase(GLenum target,GLuint first,GLsizei count,const GLuint * buffers)5059*61046927SAndroid Build Coastguard Worker _mesa_BindBuffersBase(GLenum target, GLuint first, GLsizei count,
5060*61046927SAndroid Build Coastguard Worker const GLuint *buffers)
5061*61046927SAndroid Build Coastguard Worker {
5062*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5063*61046927SAndroid Build Coastguard Worker
5064*61046927SAndroid Build Coastguard Worker if (MESA_VERBOSE & VERBOSE_API) {
5065*61046927SAndroid Build Coastguard Worker _mesa_debug(ctx, "glBindBuffersBase(%s, %u, %d, %p)\n",
5066*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target), first, count, buffers);
5067*61046927SAndroid Build Coastguard Worker }
5068*61046927SAndroid Build Coastguard Worker
5069*61046927SAndroid Build Coastguard Worker switch (target) {
5070*61046927SAndroid Build Coastguard Worker case GL_TRANSFORM_FEEDBACK_BUFFER:
5071*61046927SAndroid Build Coastguard Worker bind_xfb_buffers(ctx, first, count, buffers, false, NULL, NULL,
5072*61046927SAndroid Build Coastguard Worker "glBindBuffersBase");
5073*61046927SAndroid Build Coastguard Worker return;
5074*61046927SAndroid Build Coastguard Worker case GL_UNIFORM_BUFFER:
5075*61046927SAndroid Build Coastguard Worker bind_uniform_buffers(ctx, first, count, buffers, false, NULL, NULL,
5076*61046927SAndroid Build Coastguard Worker "glBindBuffersBase");
5077*61046927SAndroid Build Coastguard Worker return;
5078*61046927SAndroid Build Coastguard Worker case GL_SHADER_STORAGE_BUFFER:
5079*61046927SAndroid Build Coastguard Worker bind_shader_storage_buffers(ctx, first, count, buffers, false, NULL, NULL,
5080*61046927SAndroid Build Coastguard Worker "glBindBuffersBase");
5081*61046927SAndroid Build Coastguard Worker return;
5082*61046927SAndroid Build Coastguard Worker case GL_ATOMIC_COUNTER_BUFFER:
5083*61046927SAndroid Build Coastguard Worker bind_atomic_buffers(ctx, first, count, buffers, false, NULL, NULL,
5084*61046927SAndroid Build Coastguard Worker "glBindBuffersBase");
5085*61046927SAndroid Build Coastguard Worker return;
5086*61046927SAndroid Build Coastguard Worker default:
5087*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_ENUM, "glBindBuffersBase(target=%s)",
5088*61046927SAndroid Build Coastguard Worker _mesa_enum_to_string(target));
5089*61046927SAndroid Build Coastguard Worker break;
5090*61046927SAndroid Build Coastguard Worker }
5091*61046927SAndroid Build Coastguard Worker }
5092*61046927SAndroid Build Coastguard Worker
5093*61046927SAndroid Build Coastguard Worker /**
5094*61046927SAndroid Build Coastguard Worker * Called via glInvalidateBuffer(Sub)Data.
5095*61046927SAndroid Build Coastguard Worker */
5096*61046927SAndroid Build Coastguard Worker static void
bufferobj_invalidate(struct gl_context * ctx,struct gl_buffer_object * obj,GLintptr offset,GLsizeiptr size)5097*61046927SAndroid Build Coastguard Worker bufferobj_invalidate(struct gl_context *ctx,
5098*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *obj,
5099*61046927SAndroid Build Coastguard Worker GLintptr offset,
5100*61046927SAndroid Build Coastguard Worker GLsizeiptr size)
5101*61046927SAndroid Build Coastguard Worker {
5102*61046927SAndroid Build Coastguard Worker struct pipe_context *pipe = ctx->pipe;
5103*61046927SAndroid Build Coastguard Worker
5104*61046927SAndroid Build Coastguard Worker /* We ignore partial invalidates. */
5105*61046927SAndroid Build Coastguard Worker if (offset != 0 || size != obj->Size)
5106*61046927SAndroid Build Coastguard Worker return;
5107*61046927SAndroid Build Coastguard Worker
5108*61046927SAndroid Build Coastguard Worker /* If the buffer is mapped, we can't invalidate it. */
5109*61046927SAndroid Build Coastguard Worker if (!obj->buffer || _mesa_bufferobj_mapped(obj, MAP_USER))
5110*61046927SAndroid Build Coastguard Worker return;
5111*61046927SAndroid Build Coastguard Worker
5112*61046927SAndroid Build Coastguard Worker pipe->invalidate_resource(pipe, obj->buffer);
5113*61046927SAndroid Build Coastguard Worker }
5114*61046927SAndroid Build Coastguard Worker
5115*61046927SAndroid Build Coastguard Worker static ALWAYS_INLINE void
invalidate_buffer_subdata(struct gl_context * ctx,struct gl_buffer_object * bufObj,GLintptr offset,GLsizeiptr length)5116*61046927SAndroid Build Coastguard Worker invalidate_buffer_subdata(struct gl_context *ctx,
5117*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj, GLintptr offset,
5118*61046927SAndroid Build Coastguard Worker GLsizeiptr length)
5119*61046927SAndroid Build Coastguard Worker {
5120*61046927SAndroid Build Coastguard Worker if (ctx->has_invalidate_buffer)
5121*61046927SAndroid Build Coastguard Worker bufferobj_invalidate(ctx, bufObj, offset, length);
5122*61046927SAndroid Build Coastguard Worker }
5123*61046927SAndroid Build Coastguard Worker
5124*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateBufferSubData_no_error(GLuint buffer,GLintptr offset,GLsizeiptr length)5125*61046927SAndroid Build Coastguard Worker _mesa_InvalidateBufferSubData_no_error(GLuint buffer, GLintptr offset,
5126*61046927SAndroid Build Coastguard Worker GLsizeiptr length)
5127*61046927SAndroid Build Coastguard Worker {
5128*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5129*61046927SAndroid Build Coastguard Worker
5130*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer);
5131*61046927SAndroid Build Coastguard Worker invalidate_buffer_subdata(ctx, bufObj, offset, length);
5132*61046927SAndroid Build Coastguard Worker }
5133*61046927SAndroid Build Coastguard Worker
5134*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateBufferSubData(GLuint buffer,GLintptr offset,GLsizeiptr length)5135*61046927SAndroid Build Coastguard Worker _mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset,
5136*61046927SAndroid Build Coastguard Worker GLsizeiptr length)
5137*61046927SAndroid Build Coastguard Worker {
5138*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5139*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
5140*61046927SAndroid Build Coastguard Worker const GLintptr end = offset + length;
5141*61046927SAndroid Build Coastguard Worker
5142*61046927SAndroid Build Coastguard Worker /* Section 6.5 (Invalidating Buffer Data) of the OpenGL 4.5 (Compatibility
5143*61046927SAndroid Build Coastguard Worker * Profile) spec says:
5144*61046927SAndroid Build Coastguard Worker *
5145*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated if buffer is zero or is not the
5146*61046927SAndroid Build Coastguard Worker * name of an existing buffer object."
5147*61046927SAndroid Build Coastguard Worker */
5148*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
5149*61046927SAndroid Build Coastguard Worker if (!bufObj || bufObj == &DummyBufferObject) {
5150*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
5151*61046927SAndroid Build Coastguard Worker "glInvalidateBufferSubData(name = %u) invalid object",
5152*61046927SAndroid Build Coastguard Worker buffer);
5153*61046927SAndroid Build Coastguard Worker return;
5154*61046927SAndroid Build Coastguard Worker }
5155*61046927SAndroid Build Coastguard Worker
5156*61046927SAndroid Build Coastguard Worker /* The GL_ARB_invalidate_subdata spec says:
5157*61046927SAndroid Build Coastguard Worker *
5158*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated if <offset> or <length> is
5159*61046927SAndroid Build Coastguard Worker * negative, or if <offset> + <length> is greater than the value of
5160*61046927SAndroid Build Coastguard Worker * BUFFER_SIZE."
5161*61046927SAndroid Build Coastguard Worker */
5162*61046927SAndroid Build Coastguard Worker if (offset < 0 || length < 0 || end > bufObj->Size) {
5163*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
5164*61046927SAndroid Build Coastguard Worker "glInvalidateBufferSubData(invalid offset or length)");
5165*61046927SAndroid Build Coastguard Worker return;
5166*61046927SAndroid Build Coastguard Worker }
5167*61046927SAndroid Build Coastguard Worker
5168*61046927SAndroid Build Coastguard Worker /* The OpenGL 4.4 (Core Profile) spec says:
5169*61046927SAndroid Build Coastguard Worker *
5170*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if buffer is currently
5171*61046927SAndroid Build Coastguard Worker * mapped by MapBuffer or if the invalidate range intersects the range
5172*61046927SAndroid Build Coastguard Worker * currently mapped by MapBufferRange, unless it was mapped
5173*61046927SAndroid Build Coastguard Worker * with MAP_PERSISTENT_BIT set in the MapBufferRange access flags."
5174*61046927SAndroid Build Coastguard Worker */
5175*61046927SAndroid Build Coastguard Worker if (!(bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_PERSISTENT_BIT) &&
5176*61046927SAndroid Build Coastguard Worker bufferobj_range_mapped(bufObj, offset, length)) {
5177*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
5178*61046927SAndroid Build Coastguard Worker "glInvalidateBufferSubData(intersection with mapped "
5179*61046927SAndroid Build Coastguard Worker "range)");
5180*61046927SAndroid Build Coastguard Worker return;
5181*61046927SAndroid Build Coastguard Worker }
5182*61046927SAndroid Build Coastguard Worker
5183*61046927SAndroid Build Coastguard Worker invalidate_buffer_subdata(ctx, bufObj, offset, length);
5184*61046927SAndroid Build Coastguard Worker }
5185*61046927SAndroid Build Coastguard Worker
5186*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateBufferData_no_error(GLuint buffer)5187*61046927SAndroid Build Coastguard Worker _mesa_InvalidateBufferData_no_error(GLuint buffer)
5188*61046927SAndroid Build Coastguard Worker {
5189*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5190*61046927SAndroid Build Coastguard Worker
5191*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj =_mesa_lookup_bufferobj(ctx, buffer);
5192*61046927SAndroid Build Coastguard Worker invalidate_buffer_subdata(ctx, bufObj, 0, bufObj->Size);
5193*61046927SAndroid Build Coastguard Worker }
5194*61046927SAndroid Build Coastguard Worker
5195*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_InvalidateBufferData(GLuint buffer)5196*61046927SAndroid Build Coastguard Worker _mesa_InvalidateBufferData(GLuint buffer)
5197*61046927SAndroid Build Coastguard Worker {
5198*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5199*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufObj;
5200*61046927SAndroid Build Coastguard Worker
5201*61046927SAndroid Build Coastguard Worker /* Section 6.5 (Invalidating Buffer Data) of the OpenGL 4.5 (Compatibility
5202*61046927SAndroid Build Coastguard Worker * Profile) spec says:
5203*61046927SAndroid Build Coastguard Worker *
5204*61046927SAndroid Build Coastguard Worker * "An INVALID_VALUE error is generated if buffer is zero or is not the
5205*61046927SAndroid Build Coastguard Worker * name of an existing buffer object."
5206*61046927SAndroid Build Coastguard Worker */
5207*61046927SAndroid Build Coastguard Worker bufObj = _mesa_lookup_bufferobj(ctx, buffer);
5208*61046927SAndroid Build Coastguard Worker if (!bufObj || bufObj == &DummyBufferObject) {
5209*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
5210*61046927SAndroid Build Coastguard Worker "glInvalidateBufferData(name = %u) invalid object",
5211*61046927SAndroid Build Coastguard Worker buffer);
5212*61046927SAndroid Build Coastguard Worker return;
5213*61046927SAndroid Build Coastguard Worker }
5214*61046927SAndroid Build Coastguard Worker
5215*61046927SAndroid Build Coastguard Worker /* The OpenGL 4.4 (Core Profile) spec says:
5216*61046927SAndroid Build Coastguard Worker *
5217*61046927SAndroid Build Coastguard Worker * "An INVALID_OPERATION error is generated if buffer is currently
5218*61046927SAndroid Build Coastguard Worker * mapped by MapBuffer or if the invalidate range intersects the range
5219*61046927SAndroid Build Coastguard Worker * currently mapped by MapBufferRange, unless it was mapped
5220*61046927SAndroid Build Coastguard Worker * with MAP_PERSISTENT_BIT set in the MapBufferRange access flags."
5221*61046927SAndroid Build Coastguard Worker */
5222*61046927SAndroid Build Coastguard Worker if (_mesa_check_disallowed_mapping(bufObj)) {
5223*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
5224*61046927SAndroid Build Coastguard Worker "glInvalidateBufferData(intersection with mapped "
5225*61046927SAndroid Build Coastguard Worker "range)");
5226*61046927SAndroid Build Coastguard Worker return;
5227*61046927SAndroid Build Coastguard Worker }
5228*61046927SAndroid Build Coastguard Worker
5229*61046927SAndroid Build Coastguard Worker invalidate_buffer_subdata(ctx, bufObj, 0, bufObj->Size);
5230*61046927SAndroid Build Coastguard Worker }
5231*61046927SAndroid Build Coastguard Worker
5232*61046927SAndroid Build Coastguard Worker static void
buffer_page_commitment(struct gl_context * ctx,struct gl_buffer_object * bufferObj,GLintptr offset,GLsizeiptr size,GLboolean commit,const char * func)5233*61046927SAndroid Build Coastguard Worker buffer_page_commitment(struct gl_context *ctx,
5234*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufferObj,
5235*61046927SAndroid Build Coastguard Worker GLintptr offset, GLsizeiptr size,
5236*61046927SAndroid Build Coastguard Worker GLboolean commit, const char *func)
5237*61046927SAndroid Build Coastguard Worker {
5238*61046927SAndroid Build Coastguard Worker if (!(bufferObj->StorageFlags & GL_SPARSE_STORAGE_BIT_ARB)) {
5239*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION, "%s(not a sparse buffer object)",
5240*61046927SAndroid Build Coastguard Worker func);
5241*61046927SAndroid Build Coastguard Worker return;
5242*61046927SAndroid Build Coastguard Worker }
5243*61046927SAndroid Build Coastguard Worker
5244*61046927SAndroid Build Coastguard Worker if (size < 0 || size > bufferObj->Size ||
5245*61046927SAndroid Build Coastguard Worker offset < 0 || offset > bufferObj->Size - size) {
5246*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(out of bounds)",
5247*61046927SAndroid Build Coastguard Worker func);
5248*61046927SAndroid Build Coastguard Worker return;
5249*61046927SAndroid Build Coastguard Worker }
5250*61046927SAndroid Build Coastguard Worker
5251*61046927SAndroid Build Coastguard Worker /* The GL_ARB_sparse_buffer extension specification says:
5252*61046927SAndroid Build Coastguard Worker *
5253*61046927SAndroid Build Coastguard Worker * "INVALID_VALUE is generated by BufferPageCommitmentARB if <offset> is
5254*61046927SAndroid Build Coastguard Worker * not an integer multiple of SPARSE_BUFFER_PAGE_SIZE_ARB, or if <size>
5255*61046927SAndroid Build Coastguard Worker * is not an integer multiple of SPARSE_BUFFER_PAGE_SIZE_ARB and does
5256*61046927SAndroid Build Coastguard Worker * not extend to the end of the buffer's data store."
5257*61046927SAndroid Build Coastguard Worker */
5258*61046927SAndroid Build Coastguard Worker if (offset % ctx->Const.SparseBufferPageSize != 0) {
5259*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset not aligned to page size)",
5260*61046927SAndroid Build Coastguard Worker func);
5261*61046927SAndroid Build Coastguard Worker return;
5262*61046927SAndroid Build Coastguard Worker }
5263*61046927SAndroid Build Coastguard Worker
5264*61046927SAndroid Build Coastguard Worker if (size % ctx->Const.SparseBufferPageSize != 0 &&
5265*61046927SAndroid Build Coastguard Worker offset + size != bufferObj->Size) {
5266*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE, "%s(size not aligned to page size)",
5267*61046927SAndroid Build Coastguard Worker func);
5268*61046927SAndroid Build Coastguard Worker return;
5269*61046927SAndroid Build Coastguard Worker }
5270*61046927SAndroid Build Coastguard Worker
5271*61046927SAndroid Build Coastguard Worker struct pipe_context *pipe = ctx->pipe;
5272*61046927SAndroid Build Coastguard Worker struct pipe_box box;
5273*61046927SAndroid Build Coastguard Worker
5274*61046927SAndroid Build Coastguard Worker u_box_1d(offset, size, &box);
5275*61046927SAndroid Build Coastguard Worker
5276*61046927SAndroid Build Coastguard Worker if (!pipe->resource_commit(pipe, bufferObj->buffer, 0, &box, commit)) {
5277*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferPageCommitmentARB(out of memory)");
5278*61046927SAndroid Build Coastguard Worker }
5279*61046927SAndroid Build Coastguard Worker }
5280*61046927SAndroid Build Coastguard Worker
5281*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_BufferPageCommitmentARB(GLenum target,GLintptr offset,GLsizeiptr size,GLboolean commit)5282*61046927SAndroid Build Coastguard Worker _mesa_BufferPageCommitmentARB(GLenum target, GLintptr offset, GLsizeiptr size,
5283*61046927SAndroid Build Coastguard Worker GLboolean commit)
5284*61046927SAndroid Build Coastguard Worker {
5285*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5286*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufferObj;
5287*61046927SAndroid Build Coastguard Worker
5288*61046927SAndroid Build Coastguard Worker bufferObj = get_buffer(ctx, "glBufferPageCommitmentARB", target,
5289*61046927SAndroid Build Coastguard Worker GL_INVALID_ENUM);
5290*61046927SAndroid Build Coastguard Worker if (!bufferObj)
5291*61046927SAndroid Build Coastguard Worker return;
5292*61046927SAndroid Build Coastguard Worker
5293*61046927SAndroid Build Coastguard Worker buffer_page_commitment(ctx, bufferObj, offset, size, commit,
5294*61046927SAndroid Build Coastguard Worker "glBufferPageCommitmentARB");
5295*61046927SAndroid Build Coastguard Worker }
5296*61046927SAndroid Build Coastguard Worker
5297*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferPageCommitmentARB(GLuint buffer,GLintptr offset,GLsizeiptr size,GLboolean commit)5298*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferPageCommitmentARB(GLuint buffer, GLintptr offset,
5299*61046927SAndroid Build Coastguard Worker GLsizeiptr size, GLboolean commit)
5300*61046927SAndroid Build Coastguard Worker {
5301*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5302*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufferObj;
5303*61046927SAndroid Build Coastguard Worker
5304*61046927SAndroid Build Coastguard Worker bufferObj = _mesa_lookup_bufferobj(ctx, buffer);
5305*61046927SAndroid Build Coastguard Worker if (!bufferObj || bufferObj == &DummyBufferObject) {
5306*61046927SAndroid Build Coastguard Worker /* Note: the extension spec is not clear about the excpected error value. */
5307*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_VALUE,
5308*61046927SAndroid Build Coastguard Worker "glNamedBufferPageCommitmentARB(name = %u) invalid object",
5309*61046927SAndroid Build Coastguard Worker buffer);
5310*61046927SAndroid Build Coastguard Worker return;
5311*61046927SAndroid Build Coastguard Worker }
5312*61046927SAndroid Build Coastguard Worker
5313*61046927SAndroid Build Coastguard Worker buffer_page_commitment(ctx, bufferObj, offset, size, commit,
5314*61046927SAndroid Build Coastguard Worker "glNamedBufferPageCommitmentARB");
5315*61046927SAndroid Build Coastguard Worker }
5316*61046927SAndroid Build Coastguard Worker
5317*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_NamedBufferPageCommitmentEXT(GLuint buffer,GLintptr offset,GLsizeiptr size,GLboolean commit)5318*61046927SAndroid Build Coastguard Worker _mesa_NamedBufferPageCommitmentEXT(GLuint buffer, GLintptr offset,
5319*61046927SAndroid Build Coastguard Worker GLsizeiptr size, GLboolean commit)
5320*61046927SAndroid Build Coastguard Worker {
5321*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
5322*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *bufferObj;
5323*61046927SAndroid Build Coastguard Worker
5324*61046927SAndroid Build Coastguard Worker /* Use NamedBuffer* functions logic from EXT_direct_state_access */
5325*61046927SAndroid Build Coastguard Worker if (buffer != 0) {
5326*61046927SAndroid Build Coastguard Worker bufferObj = _mesa_lookup_bufferobj(ctx, buffer);
5327*61046927SAndroid Build Coastguard Worker if (!handle_bind_buffer_gen(ctx, buffer, &bufferObj,
5328*61046927SAndroid Build Coastguard Worker "glNamedBufferPageCommitmentEXT", false))
5329*61046927SAndroid Build Coastguard Worker return;
5330*61046927SAndroid Build Coastguard Worker } else {
5331*61046927SAndroid Build Coastguard Worker /* GL_EXT_direct_state_access says about NamedBuffer* functions:
5332*61046927SAndroid Build Coastguard Worker *
5333*61046927SAndroid Build Coastguard Worker * There is no buffer corresponding to the name zero, these commands
5334*61046927SAndroid Build Coastguard Worker * generate the INVALID_OPERATION error if the buffer parameter is
5335*61046927SAndroid Build Coastguard Worker * zero.
5336*61046927SAndroid Build Coastguard Worker */
5337*61046927SAndroid Build Coastguard Worker _mesa_error(ctx, GL_INVALID_OPERATION,
5338*61046927SAndroid Build Coastguard Worker "glNamedBufferPageCommitmentEXT(buffer = 0)");
5339*61046927SAndroid Build Coastguard Worker return;
5340*61046927SAndroid Build Coastguard Worker }
5341*61046927SAndroid Build Coastguard Worker buffer_page_commitment(ctx, bufferObj, offset, size, commit,
5342*61046927SAndroid Build Coastguard Worker "glNamedBufferPageCommitmentEXT");
5343*61046927SAndroid Build Coastguard Worker }
5344