1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2012 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "main/glthread_marshal.h"
25*61046927SAndroid Build Coastguard Worker #include "main/dispatch.h"
26*61046927SAndroid Build Coastguard Worker #include "main/bufferobj.h"
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker /**
29*61046927SAndroid Build Coastguard Worker * Create an upload buffer. This is called from the app thread, so everything
30*61046927SAndroid Build Coastguard Worker * has to be thread-safe in the driver.
31*61046927SAndroid Build Coastguard Worker */
32*61046927SAndroid Build Coastguard Worker static struct gl_buffer_object *
new_upload_buffer(struct gl_context * ctx,GLsizeiptr size,uint8_t ** ptr)33*61046927SAndroid Build Coastguard Worker new_upload_buffer(struct gl_context *ctx, GLsizeiptr size, uint8_t **ptr)
34*61046927SAndroid Build Coastguard Worker {
35*61046927SAndroid Build Coastguard Worker /* id 0 is used to avoid returning invalid binding values to apps */
36*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *obj =
37*61046927SAndroid Build Coastguard Worker _mesa_bufferobj_alloc(ctx, 0);
38*61046927SAndroid Build Coastguard Worker if (!obj)
39*61046927SAndroid Build Coastguard Worker return NULL;
40*61046927SAndroid Build Coastguard Worker
41*61046927SAndroid Build Coastguard Worker obj->Immutable = true;
42*61046927SAndroid Build Coastguard Worker obj->GLThreadInternal = true;
43*61046927SAndroid Build Coastguard Worker
44*61046927SAndroid Build Coastguard Worker if (!_mesa_bufferobj_data(ctx, GL_ARRAY_BUFFER, size, NULL,
45*61046927SAndroid Build Coastguard Worker GL_WRITE_ONLY,
46*61046927SAndroid Build Coastguard Worker GL_CLIENT_STORAGE_BIT | GL_MAP_WRITE_BIT,
47*61046927SAndroid Build Coastguard Worker obj)) {
48*61046927SAndroid Build Coastguard Worker _mesa_delete_buffer_object(ctx, obj);
49*61046927SAndroid Build Coastguard Worker return NULL;
50*61046927SAndroid Build Coastguard Worker }
51*61046927SAndroid Build Coastguard Worker
52*61046927SAndroid Build Coastguard Worker *ptr = _mesa_bufferobj_map_range(ctx, 0, size,
53*61046927SAndroid Build Coastguard Worker GL_MAP_WRITE_BIT |
54*61046927SAndroid Build Coastguard Worker GL_MAP_UNSYNCHRONIZED_BIT |
55*61046927SAndroid Build Coastguard Worker MESA_MAP_THREAD_SAFE_BIT,
56*61046927SAndroid Build Coastguard Worker obj, MAP_GLTHREAD);
57*61046927SAndroid Build Coastguard Worker if (!*ptr) {
58*61046927SAndroid Build Coastguard Worker _mesa_delete_buffer_object(ctx, obj);
59*61046927SAndroid Build Coastguard Worker return NULL;
60*61046927SAndroid Build Coastguard Worker }
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker return obj;
63*61046927SAndroid Build Coastguard Worker }
64*61046927SAndroid Build Coastguard Worker
65*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_release_upload_buffer(struct gl_context * ctx)66*61046927SAndroid Build Coastguard Worker _mesa_glthread_release_upload_buffer(struct gl_context *ctx)
67*61046927SAndroid Build Coastguard Worker {
68*61046927SAndroid Build Coastguard Worker struct glthread_state *glthread = &ctx->GLThread;
69*61046927SAndroid Build Coastguard Worker
70*61046927SAndroid Build Coastguard Worker if (glthread->upload_buffer_private_refcount > 0) {
71*61046927SAndroid Build Coastguard Worker p_atomic_add(&glthread->upload_buffer->RefCount,
72*61046927SAndroid Build Coastguard Worker -glthread->upload_buffer_private_refcount);
73*61046927SAndroid Build Coastguard Worker glthread->upload_buffer_private_refcount = 0;
74*61046927SAndroid Build Coastguard Worker }
75*61046927SAndroid Build Coastguard Worker _mesa_reference_buffer_object(ctx, &glthread->upload_buffer, NULL);
76*61046927SAndroid Build Coastguard Worker }
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_upload(struct gl_context * ctx,const void * data,GLsizeiptr size,unsigned * out_offset,struct gl_buffer_object ** out_buffer,uint8_t ** out_ptr,unsigned start_offset)79*61046927SAndroid Build Coastguard Worker _mesa_glthread_upload(struct gl_context *ctx, const void *data,
80*61046927SAndroid Build Coastguard Worker GLsizeiptr size, unsigned *out_offset,
81*61046927SAndroid Build Coastguard Worker struct gl_buffer_object **out_buffer,
82*61046927SAndroid Build Coastguard Worker uint8_t **out_ptr,
83*61046927SAndroid Build Coastguard Worker unsigned start_offset)
84*61046927SAndroid Build Coastguard Worker {
85*61046927SAndroid Build Coastguard Worker struct glthread_state *glthread = &ctx->GLThread;
86*61046927SAndroid Build Coastguard Worker const unsigned default_size = 1024 * 1024;
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker if (unlikely(size > INT_MAX))
89*61046927SAndroid Build Coastguard Worker return;
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker /* The alignment was chosen arbitrarily. */
92*61046927SAndroid Build Coastguard Worker unsigned offset = align(glthread->upload_offset, size <= 4 ? 4 : 8) + start_offset;
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker /* Allocate a new buffer if needed. */
95*61046927SAndroid Build Coastguard Worker if (unlikely(!glthread->upload_buffer || offset + size > default_size)) {
96*61046927SAndroid Build Coastguard Worker /* If the size is greater than the buffer size, allocate a separate buffer
97*61046927SAndroid Build Coastguard Worker * just for this upload.
98*61046927SAndroid Build Coastguard Worker */
99*61046927SAndroid Build Coastguard Worker if (unlikely(start_offset + size > default_size)) {
100*61046927SAndroid Build Coastguard Worker uint8_t *ptr;
101*61046927SAndroid Build Coastguard Worker
102*61046927SAndroid Build Coastguard Worker assert(*out_buffer == NULL);
103*61046927SAndroid Build Coastguard Worker *out_buffer = new_upload_buffer(ctx, size + start_offset, &ptr);
104*61046927SAndroid Build Coastguard Worker if (!*out_buffer)
105*61046927SAndroid Build Coastguard Worker return;
106*61046927SAndroid Build Coastguard Worker
107*61046927SAndroid Build Coastguard Worker ptr += start_offset;
108*61046927SAndroid Build Coastguard Worker *out_offset = start_offset;
109*61046927SAndroid Build Coastguard Worker if (data)
110*61046927SAndroid Build Coastguard Worker memcpy(ptr, data, size);
111*61046927SAndroid Build Coastguard Worker else
112*61046927SAndroid Build Coastguard Worker *out_ptr = ptr;
113*61046927SAndroid Build Coastguard Worker return;
114*61046927SAndroid Build Coastguard Worker }
115*61046927SAndroid Build Coastguard Worker
116*61046927SAndroid Build Coastguard Worker _mesa_glthread_release_upload_buffer(ctx);
117*61046927SAndroid Build Coastguard Worker
118*61046927SAndroid Build Coastguard Worker glthread->upload_buffer =
119*61046927SAndroid Build Coastguard Worker new_upload_buffer(ctx, default_size, &glthread->upload_ptr);
120*61046927SAndroid Build Coastguard Worker glthread->upload_offset = 0;
121*61046927SAndroid Build Coastguard Worker offset = start_offset;
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker /* Since atomic operations are very very slow when 2 threads are not
124*61046927SAndroid Build Coastguard Worker * sharing one L3 cache (which can happen on AMD Zen), prevent using
125*61046927SAndroid Build Coastguard Worker * atomics as follows:
126*61046927SAndroid Build Coastguard Worker *
127*61046927SAndroid Build Coastguard Worker * This function has to return a buffer reference to the caller.
128*61046927SAndroid Build Coastguard Worker * Instead of atomic_inc for every call, it does all possible future
129*61046927SAndroid Build Coastguard Worker * increments in advance when the upload buffer is allocated.
130*61046927SAndroid Build Coastguard Worker * The maximum number of times the function can be called per upload
131*61046927SAndroid Build Coastguard Worker * buffer is default_size, because the minimum allocation size is 1.
132*61046927SAndroid Build Coastguard Worker * Therefore the function can only return default_size number of
133*61046927SAndroid Build Coastguard Worker * references at most, so we will never need more. This is the number
134*61046927SAndroid Build Coastguard Worker * that is added to RefCount at allocation.
135*61046927SAndroid Build Coastguard Worker *
136*61046927SAndroid Build Coastguard Worker * upload_buffer_private_refcount tracks how many buffer references
137*61046927SAndroid Build Coastguard Worker * are left to return to callers. If the buffer is full and there are
138*61046927SAndroid Build Coastguard Worker * still references left, they are atomically subtracted from RefCount
139*61046927SAndroid Build Coastguard Worker * before the buffer is unreferenced.
140*61046927SAndroid Build Coastguard Worker *
141*61046927SAndroid Build Coastguard Worker * This can increase performance by 20%.
142*61046927SAndroid Build Coastguard Worker */
143*61046927SAndroid Build Coastguard Worker glthread->upload_buffer->RefCount += default_size;
144*61046927SAndroid Build Coastguard Worker glthread->upload_buffer_private_refcount = default_size;
145*61046927SAndroid Build Coastguard Worker }
146*61046927SAndroid Build Coastguard Worker
147*61046927SAndroid Build Coastguard Worker /* Upload data. */
148*61046927SAndroid Build Coastguard Worker if (data)
149*61046927SAndroid Build Coastguard Worker memcpy(glthread->upload_ptr + offset, data, size);
150*61046927SAndroid Build Coastguard Worker else
151*61046927SAndroid Build Coastguard Worker *out_ptr = glthread->upload_ptr + offset;
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker glthread->upload_offset = offset + size;
154*61046927SAndroid Build Coastguard Worker *out_offset = offset;
155*61046927SAndroid Build Coastguard Worker
156*61046927SAndroid Build Coastguard Worker assert(*out_buffer == NULL);
157*61046927SAndroid Build Coastguard Worker assert(glthread->upload_buffer_private_refcount > 0);
158*61046927SAndroid Build Coastguard Worker *out_buffer = glthread->upload_buffer;
159*61046927SAndroid Build Coastguard Worker glthread->upload_buffer_private_refcount--;
160*61046927SAndroid Build Coastguard Worker }
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker /** Tracks the current bindings for the vertex array and index array buffers.
163*61046927SAndroid Build Coastguard Worker *
164*61046927SAndroid Build Coastguard Worker * This is part of what we need to enable glthread on compat-GL contexts that
165*61046927SAndroid Build Coastguard Worker * happen to use VBOs, without also supporting the full tracking of VBO vs
166*61046927SAndroid Build Coastguard Worker * user vertex array bindings per attribute on each vertex array for
167*61046927SAndroid Build Coastguard Worker * determining what to upload at draw call time.
168*61046927SAndroid Build Coastguard Worker *
169*61046927SAndroid Build Coastguard Worker * Note that GL core makes it so that a buffer binding with an invalid handle
170*61046927SAndroid Build Coastguard Worker * in the "buffer" parameter will throw an error, and then a
171*61046927SAndroid Build Coastguard Worker * glVertexAttribPointer() that followsmight not end up pointing at a VBO.
172*61046927SAndroid Build Coastguard Worker * However, in GL core the draw call would throw an error as well, so we don't
173*61046927SAndroid Build Coastguard Worker * really care if our tracking is wrong for this case -- we never need to
174*61046927SAndroid Build Coastguard Worker * marshal user data for draw calls, and the unmarshal will just generate an
175*61046927SAndroid Build Coastguard Worker * error or not as appropriate.
176*61046927SAndroid Build Coastguard Worker *
177*61046927SAndroid Build Coastguard Worker * For compatibility GL, we do need to accurately know whether the draw call
178*61046927SAndroid Build Coastguard Worker * on the unmarshal side will dereference a user pointer or load data from a
179*61046927SAndroid Build Coastguard Worker * VBO per vertex. That would make it seem like we need to track whether a
180*61046927SAndroid Build Coastguard Worker * "buffer" is valid, so that we can know when an error will be generated
181*61046927SAndroid Build Coastguard Worker * instead of updating the binding. However, compat GL has the ridiculous
182*61046927SAndroid Build Coastguard Worker * feature that if you pass a bad name, it just gens a buffer object for you,
183*61046927SAndroid Build Coastguard Worker * so we escape without having to know if things are valid or not.
184*61046927SAndroid Build Coastguard Worker */
185*61046927SAndroid Build Coastguard Worker static void
_mesa_glthread_BindBuffer(struct gl_context * ctx,GLenum target,GLuint buffer)186*61046927SAndroid Build Coastguard Worker _mesa_glthread_BindBuffer(struct gl_context *ctx, GLenum target, GLuint buffer)
187*61046927SAndroid Build Coastguard Worker {
188*61046927SAndroid Build Coastguard Worker struct glthread_state *glthread = &ctx->GLThread;
189*61046927SAndroid Build Coastguard Worker
190*61046927SAndroid Build Coastguard Worker switch (target) {
191*61046927SAndroid Build Coastguard Worker case GL_ARRAY_BUFFER:
192*61046927SAndroid Build Coastguard Worker glthread->CurrentArrayBufferName = buffer;
193*61046927SAndroid Build Coastguard Worker break;
194*61046927SAndroid Build Coastguard Worker case GL_ELEMENT_ARRAY_BUFFER:
195*61046927SAndroid Build Coastguard Worker /* The current element array buffer binding is actually tracked in the
196*61046927SAndroid Build Coastguard Worker * vertex array object instead of the context, so this would need to
197*61046927SAndroid Build Coastguard Worker * change on vertex array object updates.
198*61046927SAndroid Build Coastguard Worker */
199*61046927SAndroid Build Coastguard Worker glthread->CurrentVAO->CurrentElementBufferName = buffer;
200*61046927SAndroid Build Coastguard Worker break;
201*61046927SAndroid Build Coastguard Worker case GL_DRAW_INDIRECT_BUFFER:
202*61046927SAndroid Build Coastguard Worker glthread->CurrentDrawIndirectBufferName = buffer;
203*61046927SAndroid Build Coastguard Worker break;
204*61046927SAndroid Build Coastguard Worker case GL_PIXEL_PACK_BUFFER:
205*61046927SAndroid Build Coastguard Worker glthread->CurrentPixelPackBufferName = buffer;
206*61046927SAndroid Build Coastguard Worker break;
207*61046927SAndroid Build Coastguard Worker case GL_PIXEL_UNPACK_BUFFER:
208*61046927SAndroid Build Coastguard Worker glthread->CurrentPixelUnpackBufferName = buffer;
209*61046927SAndroid Build Coastguard Worker break;
210*61046927SAndroid Build Coastguard Worker case GL_QUERY_BUFFER:
211*61046927SAndroid Build Coastguard Worker glthread->CurrentQueryBufferName = buffer;
212*61046927SAndroid Build Coastguard Worker break;
213*61046927SAndroid Build Coastguard Worker }
214*61046927SAndroid Build Coastguard Worker }
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker struct marshal_cmd_BindBuffer
217*61046927SAndroid Build Coastguard Worker {
218*61046927SAndroid Build Coastguard Worker struct marshal_cmd_base cmd_base;
219*61046927SAndroid Build Coastguard Worker GLenum16 target;
220*61046927SAndroid Build Coastguard Worker GLuint buffer;
221*61046927SAndroid Build Coastguard Worker };
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Worker uint32_t
_mesa_unmarshal_BindBuffer(struct gl_context * ctx,const struct marshal_cmd_BindBuffer * restrict cmd)224*61046927SAndroid Build Coastguard Worker _mesa_unmarshal_BindBuffer(struct gl_context *ctx,
225*61046927SAndroid Build Coastguard Worker const struct marshal_cmd_BindBuffer *restrict cmd)
226*61046927SAndroid Build Coastguard Worker {
227*61046927SAndroid Build Coastguard Worker CALL_BindBuffer(ctx->Dispatch.Current, (cmd->target, cmd->buffer));
228*61046927SAndroid Build Coastguard Worker return align(sizeof(struct marshal_cmd_BindBuffer), 8) / 8;
229*61046927SAndroid Build Coastguard Worker }
230*61046927SAndroid Build Coastguard Worker
231*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_marshal_BindBuffer(GLenum target,GLuint buffer)232*61046927SAndroid Build Coastguard Worker _mesa_marshal_BindBuffer(GLenum target, GLuint buffer)
233*61046927SAndroid Build Coastguard Worker {
234*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
235*61046927SAndroid Build Coastguard Worker _mesa_glthread_BindBuffer(ctx, target, buffer);
236*61046927SAndroid Build Coastguard Worker
237*61046927SAndroid Build Coastguard Worker struct glthread_state *glthread = &ctx->GLThread;
238*61046927SAndroid Build Coastguard Worker struct marshal_cmd_BindBuffer *last1 = glthread->LastBindBuffer1;
239*61046927SAndroid Build Coastguard Worker struct marshal_cmd_BindBuffer *last2 = glthread->LastBindBuffer2;
240*61046927SAndroid Build Coastguard Worker int cmd_size = sizeof(struct marshal_cmd_BindBuffer);
241*61046927SAndroid Build Coastguard Worker
242*61046927SAndroid Build Coastguard Worker /* Eliminate duplicated BindBuffer calls, which are plentiful
243*61046927SAndroid Build Coastguard Worker * in viewperf2020/catia. In this example, the first 2 calls are eliminated
244*61046927SAndroid Build Coastguard Worker * by glthread by keeping track of the last 2 BindBuffer calls and
245*61046927SAndroid Build Coastguard Worker * overwriting them if the target matches.
246*61046927SAndroid Build Coastguard Worker *
247*61046927SAndroid Build Coastguard Worker * glBindBuffer(GL_ARRAY_BUFFER, 0);
248*61046927SAndroid Build Coastguard Worker * glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
249*61046927SAndroid Build Coastguard Worker * glBindBuffer(GL_ARRAY_BUFFER, 6);
250*61046927SAndroid Build Coastguard Worker * glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 7);
251*61046927SAndroid Build Coastguard Worker *
252*61046927SAndroid Build Coastguard Worker * If the last call is BindBuffer...
253*61046927SAndroid Build Coastguard Worker * last2 is more recent. last1 is before last2.
254*61046927SAndroid Build Coastguard Worker */
255*61046927SAndroid Build Coastguard Worker if (_mesa_glthread_call_is_last(glthread, &last2->cmd_base,
256*61046927SAndroid Build Coastguard Worker align(cmd_size, 8) / 8)) {
257*61046927SAndroid Build Coastguard Worker /* If the target is in the last call and unbinding the buffer, overwrite
258*61046927SAndroid Build Coastguard Worker * the buffer ID there.
259*61046927SAndroid Build Coastguard Worker */
260*61046927SAndroid Build Coastguard Worker if (target == last2->target) {
261*61046927SAndroid Build Coastguard Worker /* We can't overwrite binding non-zero buffers because binding also
262*61046927SAndroid Build Coastguard Worker * creates the GL objects (like glCreateBuffers), which can't be skipped.
263*61046927SAndroid Build Coastguard Worker */
264*61046927SAndroid Build Coastguard Worker if (!last2->buffer) {
265*61046927SAndroid Build Coastguard Worker last2->buffer = buffer;
266*61046927SAndroid Build Coastguard Worker return;
267*61046927SAndroid Build Coastguard Worker }
268*61046927SAndroid Build Coastguard Worker } else if (last1 + 1 == last2 && target == last1->target &&
269*61046927SAndroid Build Coastguard Worker !last1->buffer) {
270*61046927SAndroid Build Coastguard Worker last1->buffer = buffer;
271*61046927SAndroid Build Coastguard Worker return;
272*61046927SAndroid Build Coastguard Worker }
273*61046927SAndroid Build Coastguard Worker }
274*61046927SAndroid Build Coastguard Worker
275*61046927SAndroid Build Coastguard Worker struct marshal_cmd_BindBuffer *cmd =
276*61046927SAndroid Build Coastguard Worker _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BindBuffer, cmd_size);
277*61046927SAndroid Build Coastguard Worker cmd->target = MIN2(target, 0xffff); /* clamped to 0xffff (invalid enum) */
278*61046927SAndroid Build Coastguard Worker cmd->buffer = buffer;
279*61046927SAndroid Build Coastguard Worker
280*61046927SAndroid Build Coastguard Worker glthread->LastBindBuffer1 = last2;
281*61046927SAndroid Build Coastguard Worker glthread->LastBindBuffer2 = cmd;
282*61046927SAndroid Build Coastguard Worker }
283*61046927SAndroid Build Coastguard Worker
284*61046927SAndroid Build Coastguard Worker void
_mesa_glthread_DeleteBuffers(struct gl_context * ctx,GLsizei n,const GLuint * buffers)285*61046927SAndroid Build Coastguard Worker _mesa_glthread_DeleteBuffers(struct gl_context *ctx, GLsizei n,
286*61046927SAndroid Build Coastguard Worker const GLuint *buffers)
287*61046927SAndroid Build Coastguard Worker {
288*61046927SAndroid Build Coastguard Worker struct glthread_state *glthread = &ctx->GLThread;
289*61046927SAndroid Build Coastguard Worker
290*61046927SAndroid Build Coastguard Worker if (!buffers || n < 0)
291*61046927SAndroid Build Coastguard Worker return;
292*61046927SAndroid Build Coastguard Worker
293*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < n; i++) {
294*61046927SAndroid Build Coastguard Worker GLuint id = buffers[i];
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker if (id == glthread->CurrentArrayBufferName)
297*61046927SAndroid Build Coastguard Worker _mesa_glthread_BindBuffer(ctx, GL_ARRAY_BUFFER, 0);
298*61046927SAndroid Build Coastguard Worker if (id == glthread->CurrentVAO->CurrentElementBufferName)
299*61046927SAndroid Build Coastguard Worker _mesa_glthread_BindBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, 0);
300*61046927SAndroid Build Coastguard Worker if (id == glthread->CurrentDrawIndirectBufferName)
301*61046927SAndroid Build Coastguard Worker _mesa_glthread_BindBuffer(ctx, GL_DRAW_INDIRECT_BUFFER, 0);
302*61046927SAndroid Build Coastguard Worker if (id == glthread->CurrentPixelPackBufferName)
303*61046927SAndroid Build Coastguard Worker _mesa_glthread_BindBuffer(ctx, GL_PIXEL_PACK_BUFFER, 0);
304*61046927SAndroid Build Coastguard Worker if (id == glthread->CurrentPixelUnpackBufferName)
305*61046927SAndroid Build Coastguard Worker _mesa_glthread_BindBuffer(ctx, GL_PIXEL_UNPACK_BUFFER, 0);
306*61046927SAndroid Build Coastguard Worker }
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker
309*61046927SAndroid Build Coastguard Worker /* BufferData: marshalled asynchronously */
310*61046927SAndroid Build Coastguard Worker struct marshal_cmd_BufferData
311*61046927SAndroid Build Coastguard Worker {
312*61046927SAndroid Build Coastguard Worker struct marshal_cmd_base cmd_base;
313*61046927SAndroid Build Coastguard Worker uint16_t num_slots;
314*61046927SAndroid Build Coastguard Worker GLuint target_or_name;
315*61046927SAndroid Build Coastguard Worker GLsizeiptr size;
316*61046927SAndroid Build Coastguard Worker GLenum usage;
317*61046927SAndroid Build Coastguard Worker const GLvoid *data_external_mem;
318*61046927SAndroid Build Coastguard Worker bool data_null; /* If set, no data follows for "data" */
319*61046927SAndroid Build Coastguard Worker bool named;
320*61046927SAndroid Build Coastguard Worker bool ext_dsa;
321*61046927SAndroid Build Coastguard Worker /* Next size bytes are GLubyte data[size] */
322*61046927SAndroid Build Coastguard Worker };
323*61046927SAndroid Build Coastguard Worker
324*61046927SAndroid Build Coastguard Worker uint32_t
_mesa_unmarshal_BufferData(struct gl_context * ctx,const struct marshal_cmd_BufferData * restrict cmd)325*61046927SAndroid Build Coastguard Worker _mesa_unmarshal_BufferData(struct gl_context *ctx,
326*61046927SAndroid Build Coastguard Worker const struct marshal_cmd_BufferData *restrict cmd)
327*61046927SAndroid Build Coastguard Worker {
328*61046927SAndroid Build Coastguard Worker const GLuint target_or_name = cmd->target_or_name;
329*61046927SAndroid Build Coastguard Worker const GLsizei size = cmd->size;
330*61046927SAndroid Build Coastguard Worker const GLenum usage = cmd->usage;
331*61046927SAndroid Build Coastguard Worker const void *data;
332*61046927SAndroid Build Coastguard Worker
333*61046927SAndroid Build Coastguard Worker if (cmd->data_null)
334*61046927SAndroid Build Coastguard Worker data = NULL;
335*61046927SAndroid Build Coastguard Worker else if (!cmd->named && target_or_name == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD)
336*61046927SAndroid Build Coastguard Worker data = cmd->data_external_mem;
337*61046927SAndroid Build Coastguard Worker else
338*61046927SAndroid Build Coastguard Worker data = (const void *) (cmd + 1);
339*61046927SAndroid Build Coastguard Worker
340*61046927SAndroid Build Coastguard Worker if (cmd->ext_dsa) {
341*61046927SAndroid Build Coastguard Worker CALL_NamedBufferDataEXT(ctx->Dispatch.Current,
342*61046927SAndroid Build Coastguard Worker (target_or_name, size, data, usage));
343*61046927SAndroid Build Coastguard Worker } else if (cmd->named) {
344*61046927SAndroid Build Coastguard Worker CALL_NamedBufferData(ctx->Dispatch.Current,
345*61046927SAndroid Build Coastguard Worker (target_or_name, size, data, usage));
346*61046927SAndroid Build Coastguard Worker } else {
347*61046927SAndroid Build Coastguard Worker CALL_BufferData(ctx->Dispatch.Current,
348*61046927SAndroid Build Coastguard Worker (target_or_name, size, data, usage));
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker return cmd->num_slots;
351*61046927SAndroid Build Coastguard Worker }
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker uint32_t
_mesa_unmarshal_NamedBufferData(struct gl_context * ctx,const struct marshal_cmd_NamedBufferData * restrict cmd)354*61046927SAndroid Build Coastguard Worker _mesa_unmarshal_NamedBufferData(struct gl_context *ctx,
355*61046927SAndroid Build Coastguard Worker const struct marshal_cmd_NamedBufferData *restrict cmd)
356*61046927SAndroid Build Coastguard Worker {
357*61046927SAndroid Build Coastguard Worker unreachable("never used - all BufferData variants use DISPATCH_CMD_BufferData");
358*61046927SAndroid Build Coastguard Worker return 0;
359*61046927SAndroid Build Coastguard Worker }
360*61046927SAndroid Build Coastguard Worker
361*61046927SAndroid Build Coastguard Worker uint32_t
_mesa_unmarshal_NamedBufferDataEXT(struct gl_context * ctx,const struct marshal_cmd_NamedBufferDataEXT * restrict cmd)362*61046927SAndroid Build Coastguard Worker _mesa_unmarshal_NamedBufferDataEXT(struct gl_context *ctx,
363*61046927SAndroid Build Coastguard Worker const struct marshal_cmd_NamedBufferDataEXT *restrict cmd)
364*61046927SAndroid Build Coastguard Worker {
365*61046927SAndroid Build Coastguard Worker unreachable("never used - all BufferData variants use DISPATCH_CMD_BufferData");
366*61046927SAndroid Build Coastguard Worker return 0;
367*61046927SAndroid Build Coastguard Worker }
368*61046927SAndroid Build Coastguard Worker
369*61046927SAndroid Build Coastguard Worker static void
_mesa_marshal_BufferData_merged(GLuint target_or_name,GLsizeiptr size,const GLvoid * data,GLenum usage,bool named,bool ext_dsa,const char * func)370*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferData_merged(GLuint target_or_name, GLsizeiptr size,
371*61046927SAndroid Build Coastguard Worker const GLvoid *data, GLenum usage, bool named,
372*61046927SAndroid Build Coastguard Worker bool ext_dsa, const char *func)
373*61046927SAndroid Build Coastguard Worker {
374*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
375*61046927SAndroid Build Coastguard Worker bool external_mem = !named &&
376*61046927SAndroid Build Coastguard Worker target_or_name == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD;
377*61046927SAndroid Build Coastguard Worker bool copy_data = data && !external_mem;
378*61046927SAndroid Build Coastguard Worker size_t cmd_size = sizeof(struct marshal_cmd_BufferData) + (copy_data ? size : 0);
379*61046927SAndroid Build Coastguard Worker
380*61046927SAndroid Build Coastguard Worker if (unlikely(size < 0 || size > INT_MAX || cmd_size > MARSHAL_MAX_CMD_SIZE ||
381*61046927SAndroid Build Coastguard Worker (named && target_or_name == 0))) {
382*61046927SAndroid Build Coastguard Worker _mesa_glthread_finish_before(ctx, func);
383*61046927SAndroid Build Coastguard Worker if (named) {
384*61046927SAndroid Build Coastguard Worker CALL_NamedBufferData(ctx->Dispatch.Current,
385*61046927SAndroid Build Coastguard Worker (target_or_name, size, data, usage));
386*61046927SAndroid Build Coastguard Worker } else {
387*61046927SAndroid Build Coastguard Worker CALL_BufferData(ctx->Dispatch.Current,
388*61046927SAndroid Build Coastguard Worker (target_or_name, size, data, usage));
389*61046927SAndroid Build Coastguard Worker }
390*61046927SAndroid Build Coastguard Worker return;
391*61046927SAndroid Build Coastguard Worker }
392*61046927SAndroid Build Coastguard Worker
393*61046927SAndroid Build Coastguard Worker struct marshal_cmd_BufferData *cmd =
394*61046927SAndroid Build Coastguard Worker _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BufferData,
395*61046927SAndroid Build Coastguard Worker cmd_size);
396*61046927SAndroid Build Coastguard Worker cmd->num_slots = align(cmd_size, 8) / 8;
397*61046927SAndroid Build Coastguard Worker cmd->target_or_name = target_or_name;
398*61046927SAndroid Build Coastguard Worker cmd->size = size;
399*61046927SAndroid Build Coastguard Worker cmd->usage = usage;
400*61046927SAndroid Build Coastguard Worker cmd->data_null = !data;
401*61046927SAndroid Build Coastguard Worker cmd->named = named;
402*61046927SAndroid Build Coastguard Worker cmd->ext_dsa = ext_dsa;
403*61046927SAndroid Build Coastguard Worker cmd->data_external_mem = data;
404*61046927SAndroid Build Coastguard Worker
405*61046927SAndroid Build Coastguard Worker if (copy_data) {
406*61046927SAndroid Build Coastguard Worker char *variable_data = (char *) (cmd + 1);
407*61046927SAndroid Build Coastguard Worker memcpy(variable_data, data, size);
408*61046927SAndroid Build Coastguard Worker }
409*61046927SAndroid Build Coastguard Worker }
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_marshal_BufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)412*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferData(GLenum target, GLsizeiptr size, const GLvoid * data,
413*61046927SAndroid Build Coastguard Worker GLenum usage)
414*61046927SAndroid Build Coastguard Worker {
415*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferData_merged(target, size, data, usage, false, false,
416*61046927SAndroid Build Coastguard Worker "BufferData");
417*61046927SAndroid Build Coastguard Worker }
418*61046927SAndroid Build Coastguard Worker
419*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_marshal_NamedBufferData(GLuint buffer,GLsizeiptr size,const GLvoid * data,GLenum usage)420*61046927SAndroid Build Coastguard Worker _mesa_marshal_NamedBufferData(GLuint buffer, GLsizeiptr size,
421*61046927SAndroid Build Coastguard Worker const GLvoid * data, GLenum usage)
422*61046927SAndroid Build Coastguard Worker {
423*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferData_merged(buffer, size, data, usage, true, false,
424*61046927SAndroid Build Coastguard Worker "NamedBufferData");
425*61046927SAndroid Build Coastguard Worker }
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_marshal_NamedBufferDataEXT(GLuint buffer,GLsizeiptr size,const GLvoid * data,GLenum usage)428*61046927SAndroid Build Coastguard Worker _mesa_marshal_NamedBufferDataEXT(GLuint buffer, GLsizeiptr size,
429*61046927SAndroid Build Coastguard Worker const GLvoid *data, GLenum usage)
430*61046927SAndroid Build Coastguard Worker {
431*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferData_merged(buffer, size, data, usage, true, true,
432*61046927SAndroid Build Coastguard Worker "NamedBufferDataEXT");
433*61046927SAndroid Build Coastguard Worker }
434*61046927SAndroid Build Coastguard Worker
435*61046927SAndroid Build Coastguard Worker
436*61046927SAndroid Build Coastguard Worker /* BufferSubData: marshalled asynchronously */
437*61046927SAndroid Build Coastguard Worker struct marshal_cmd_BufferSubData
438*61046927SAndroid Build Coastguard Worker {
439*61046927SAndroid Build Coastguard Worker struct marshal_cmd_base cmd_base;
440*61046927SAndroid Build Coastguard Worker uint16_t num_slots;
441*61046927SAndroid Build Coastguard Worker GLenum target_or_name;
442*61046927SAndroid Build Coastguard Worker GLintptr offset;
443*61046927SAndroid Build Coastguard Worker GLsizeiptr size;
444*61046927SAndroid Build Coastguard Worker bool named;
445*61046927SAndroid Build Coastguard Worker bool ext_dsa;
446*61046927SAndroid Build Coastguard Worker /* Next size bytes are GLubyte data[size] */
447*61046927SAndroid Build Coastguard Worker };
448*61046927SAndroid Build Coastguard Worker
449*61046927SAndroid Build Coastguard Worker uint32_t
_mesa_unmarshal_BufferSubData(struct gl_context * ctx,const struct marshal_cmd_BufferSubData * restrict cmd)450*61046927SAndroid Build Coastguard Worker _mesa_unmarshal_BufferSubData(struct gl_context *ctx,
451*61046927SAndroid Build Coastguard Worker const struct marshal_cmd_BufferSubData *restrict cmd)
452*61046927SAndroid Build Coastguard Worker {
453*61046927SAndroid Build Coastguard Worker const GLenum target_or_name = cmd->target_or_name;
454*61046927SAndroid Build Coastguard Worker const GLintptr offset = cmd->offset;
455*61046927SAndroid Build Coastguard Worker const GLsizeiptr size = cmd->size;
456*61046927SAndroid Build Coastguard Worker const void *data = (const void *) (cmd + 1);
457*61046927SAndroid Build Coastguard Worker
458*61046927SAndroid Build Coastguard Worker if (cmd->ext_dsa) {
459*61046927SAndroid Build Coastguard Worker CALL_NamedBufferSubDataEXT(ctx->Dispatch.Current,
460*61046927SAndroid Build Coastguard Worker (target_or_name, offset, size, data));
461*61046927SAndroid Build Coastguard Worker } else if (cmd->named) {
462*61046927SAndroid Build Coastguard Worker CALL_NamedBufferSubData(ctx->Dispatch.Current,
463*61046927SAndroid Build Coastguard Worker (target_or_name, offset, size, data));
464*61046927SAndroid Build Coastguard Worker } else {
465*61046927SAndroid Build Coastguard Worker CALL_BufferSubData(ctx->Dispatch.Current,
466*61046927SAndroid Build Coastguard Worker (target_or_name, offset, size, data));
467*61046927SAndroid Build Coastguard Worker }
468*61046927SAndroid Build Coastguard Worker return cmd->num_slots;
469*61046927SAndroid Build Coastguard Worker }
470*61046927SAndroid Build Coastguard Worker
471*61046927SAndroid Build Coastguard Worker uint32_t
_mesa_unmarshal_NamedBufferSubData(struct gl_context * ctx,const struct marshal_cmd_NamedBufferSubData * restrict cmd)472*61046927SAndroid Build Coastguard Worker _mesa_unmarshal_NamedBufferSubData(struct gl_context *ctx,
473*61046927SAndroid Build Coastguard Worker const struct marshal_cmd_NamedBufferSubData *restrict cmd)
474*61046927SAndroid Build Coastguard Worker {
475*61046927SAndroid Build Coastguard Worker unreachable("never used - all BufferSubData variants use DISPATCH_CMD_BufferSubData");
476*61046927SAndroid Build Coastguard Worker return 0;
477*61046927SAndroid Build Coastguard Worker }
478*61046927SAndroid Build Coastguard Worker
479*61046927SAndroid Build Coastguard Worker uint32_t
_mesa_unmarshal_NamedBufferSubDataEXT(struct gl_context * ctx,const struct marshal_cmd_NamedBufferSubDataEXT * restrict cmd)480*61046927SAndroid Build Coastguard Worker _mesa_unmarshal_NamedBufferSubDataEXT(struct gl_context *ctx,
481*61046927SAndroid Build Coastguard Worker const struct marshal_cmd_NamedBufferSubDataEXT *restrict cmd)
482*61046927SAndroid Build Coastguard Worker {
483*61046927SAndroid Build Coastguard Worker unreachable("never used - all BufferSubData variants use DISPATCH_CMD_BufferSubData");
484*61046927SAndroid Build Coastguard Worker return 0;
485*61046927SAndroid Build Coastguard Worker }
486*61046927SAndroid Build Coastguard Worker
487*61046927SAndroid Build Coastguard Worker static void
_mesa_marshal_BufferSubData_merged(GLuint target_or_name,GLintptr offset,GLsizeiptr size,const GLvoid * data,bool named,bool ext_dsa,const char * func)488*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferSubData_merged(GLuint target_or_name, GLintptr offset,
489*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid *data,
490*61046927SAndroid Build Coastguard Worker bool named, bool ext_dsa, const char *func)
491*61046927SAndroid Build Coastguard Worker {
492*61046927SAndroid Build Coastguard Worker GET_CURRENT_CONTEXT(ctx);
493*61046927SAndroid Build Coastguard Worker size_t cmd_size = sizeof(struct marshal_cmd_BufferSubData) + size;
494*61046927SAndroid Build Coastguard Worker
495*61046927SAndroid Build Coastguard Worker /* Fast path: Copy the data to an upload buffer, and use the GPU
496*61046927SAndroid Build Coastguard Worker * to copy the uploaded data to the destination buffer.
497*61046927SAndroid Build Coastguard Worker */
498*61046927SAndroid Build Coastguard Worker /* TODO: Handle offset == 0 && size < buffer_size.
499*61046927SAndroid Build Coastguard Worker * If offset == 0 and size == buffer_size, it's better to discard
500*61046927SAndroid Build Coastguard Worker * the buffer storage, but we don't know the buffer size in glthread.
501*61046927SAndroid Build Coastguard Worker */
502*61046927SAndroid Build Coastguard Worker if (ctx->Const.AllowGLThreadBufferSubDataOpt &&
503*61046927SAndroid Build Coastguard Worker ctx->Dispatch.Current != ctx->Dispatch.ContextLost &&
504*61046927SAndroid Build Coastguard Worker data && offset > 0 && size > 0) {
505*61046927SAndroid Build Coastguard Worker struct gl_buffer_object *upload_buffer = NULL;
506*61046927SAndroid Build Coastguard Worker unsigned upload_offset = 0;
507*61046927SAndroid Build Coastguard Worker
508*61046927SAndroid Build Coastguard Worker _mesa_glthread_upload(ctx, data, size, &upload_offset, &upload_buffer,
509*61046927SAndroid Build Coastguard Worker NULL, 0);
510*61046927SAndroid Build Coastguard Worker
511*61046927SAndroid Build Coastguard Worker if (upload_buffer) {
512*61046927SAndroid Build Coastguard Worker _mesa_marshal_InternalBufferSubDataCopyMESA((GLintptr)upload_buffer,
513*61046927SAndroid Build Coastguard Worker upload_offset,
514*61046927SAndroid Build Coastguard Worker target_or_name,
515*61046927SAndroid Build Coastguard Worker offset, size, named,
516*61046927SAndroid Build Coastguard Worker ext_dsa);
517*61046927SAndroid Build Coastguard Worker return;
518*61046927SAndroid Build Coastguard Worker }
519*61046927SAndroid Build Coastguard Worker }
520*61046927SAndroid Build Coastguard Worker
521*61046927SAndroid Build Coastguard Worker if (unlikely(size < 0 || size > INT_MAX || cmd_size < 0 ||
522*61046927SAndroid Build Coastguard Worker cmd_size > MARSHAL_MAX_CMD_SIZE || !data ||
523*61046927SAndroid Build Coastguard Worker (named && target_or_name == 0))) {
524*61046927SAndroid Build Coastguard Worker _mesa_glthread_finish_before(ctx, func);
525*61046927SAndroid Build Coastguard Worker if (named) {
526*61046927SAndroid Build Coastguard Worker CALL_NamedBufferSubData(ctx->Dispatch.Current,
527*61046927SAndroid Build Coastguard Worker (target_or_name, offset, size, data));
528*61046927SAndroid Build Coastguard Worker } else {
529*61046927SAndroid Build Coastguard Worker CALL_BufferSubData(ctx->Dispatch.Current,
530*61046927SAndroid Build Coastguard Worker (target_or_name, offset, size, data));
531*61046927SAndroid Build Coastguard Worker }
532*61046927SAndroid Build Coastguard Worker return;
533*61046927SAndroid Build Coastguard Worker }
534*61046927SAndroid Build Coastguard Worker
535*61046927SAndroid Build Coastguard Worker struct marshal_cmd_BufferSubData *cmd =
536*61046927SAndroid Build Coastguard Worker _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BufferSubData,
537*61046927SAndroid Build Coastguard Worker cmd_size);
538*61046927SAndroid Build Coastguard Worker cmd->num_slots = align(cmd_size, 8) / 8;
539*61046927SAndroid Build Coastguard Worker cmd->target_or_name = target_or_name;
540*61046927SAndroid Build Coastguard Worker cmd->offset = offset;
541*61046927SAndroid Build Coastguard Worker cmd->size = size;
542*61046927SAndroid Build Coastguard Worker cmd->named = named;
543*61046927SAndroid Build Coastguard Worker cmd->ext_dsa = ext_dsa;
544*61046927SAndroid Build Coastguard Worker
545*61046927SAndroid Build Coastguard Worker char *variable_data = (char *) (cmd + 1);
546*61046927SAndroid Build Coastguard Worker memcpy(variable_data, data, size);
547*61046927SAndroid Build Coastguard Worker }
548*61046927SAndroid Build Coastguard Worker
549*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_marshal_BufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)550*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
551*61046927SAndroid Build Coastguard Worker const GLvoid * data)
552*61046927SAndroid Build Coastguard Worker {
553*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferSubData_merged(target, offset, size, data, false,
554*61046927SAndroid Build Coastguard Worker false, "BufferSubData");
555*61046927SAndroid Build Coastguard Worker }
556*61046927SAndroid Build Coastguard Worker
557*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_marshal_NamedBufferSubData(GLuint buffer,GLintptr offset,GLsizeiptr size,const GLvoid * data)558*61046927SAndroid Build Coastguard Worker _mesa_marshal_NamedBufferSubData(GLuint buffer, GLintptr offset,
559*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid * data)
560*61046927SAndroid Build Coastguard Worker {
561*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferSubData_merged(buffer, offset, size, data, true,
562*61046927SAndroid Build Coastguard Worker false, "NamedBufferSubData");
563*61046927SAndroid Build Coastguard Worker }
564*61046927SAndroid Build Coastguard Worker
565*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_marshal_NamedBufferSubDataEXT(GLuint buffer,GLintptr offset,GLsizeiptr size,const GLvoid * data)566*61046927SAndroid Build Coastguard Worker _mesa_marshal_NamedBufferSubDataEXT(GLuint buffer, GLintptr offset,
567*61046927SAndroid Build Coastguard Worker GLsizeiptr size, const GLvoid * data)
568*61046927SAndroid Build Coastguard Worker {
569*61046927SAndroid Build Coastguard Worker _mesa_marshal_BufferSubData_merged(buffer, offset, size, data, true,
570*61046927SAndroid Build Coastguard Worker true, "NamedBufferSubDataEXT");
571*61046927SAndroid Build Coastguard Worker }
572