~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/mesa/main/externalobjects.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2016 Red Hat.
3
 
 *
4
 
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 
 * copy of this software and associated documentation files (the "Software"),
6
 
 * to deal in the Software without restriction, including without limitation
7
 
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 
 * and/or sell copies of the Software, and to permit persons to whom the
9
 
 * Software is furnished to do so, subject to the following conditions:
10
 
 *
11
 
 * The above copyright notice and this permission notice (including the next
12
 
 * paragraph) shall be included in all copies or substantial portions of the
13
 
 * Software.
14
 
 *
15
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 
 * DEALINGS IN THE SOFTWARE.
22
 
 */
23
 
 
24
 
#include "macros.h"
25
 
#include "mtypes.h"
26
 
#include "bufferobj.h"
27
 
#include "context.h"
28
 
#include "enums.h"
29
 
#include "externalobjects.h"
30
 
#include "teximage.h"
31
 
#include "texobj.h"
32
 
#include "glformats.h"
33
 
#include "texstorage.h"
34
 
#include "util/u_memory.h"
35
 
 
36
 
#include "pipe/p_context.h"
37
 
#include "pipe/p_screen.h"
38
 
#include "api_exec_decl.h"
39
 
 
40
 
#include "state_tracker/st_cb_bitmap.h"
41
 
#include "state_tracker/st_texture.h"
42
 
 
43
 
struct st_context;
44
 
 
45
 
#include "frontend/drm_driver.h"
46
 
#ifdef HAVE_LIBDRM
47
 
#include "drm-uapi/drm_fourcc.h"
48
 
#endif
49
 
 
50
 
static struct gl_memory_object *
51
 
memoryobj_alloc(struct gl_context *ctx, GLuint name)
52
 
{
53
 
   struct gl_memory_object *obj = CALLOC_STRUCT(gl_memory_object);
54
 
   if (!obj)
55
 
      return NULL;
56
 
 
57
 
   obj->Name = name;
58
 
   obj->Dedicated = GL_FALSE;
59
 
   return obj;
60
 
}
61
 
 
62
 
static void
63
 
import_memoryobj_fd(struct gl_context *ctx,
64
 
                    struct gl_memory_object *obj,
65
 
                    GLuint64 size,
66
 
                    int fd)
67
 
{
68
 
#if !defined(_WIN32)
69
 
   struct pipe_screen *screen = ctx->pipe->screen;
70
 
   struct winsys_handle whandle = {
71
 
      .type = WINSYS_HANDLE_TYPE_FD,
72
 
      .handle = fd,
73
 
#ifdef HAVE_LIBDRM
74
 
      .modifier = DRM_FORMAT_MOD_INVALID,
75
 
#endif
76
 
   };
77
 
 
78
 
   obj->memory = screen->memobj_create_from_handle(screen,
79
 
                                                   &whandle,
80
 
                                                   obj->Dedicated);
81
 
 
82
 
   /* We own fd, but we no longer need it. So get rid of it */
83
 
   close(fd);
84
 
#endif
85
 
}
86
 
 
87
 
/**
88
 
 * Delete a memory object.
89
 
 * Not removed from hash table here.
90
 
 */
91
 
void
92
 
_mesa_delete_memory_object(struct gl_context *ctx,
93
 
                           struct gl_memory_object *memObj)
94
 
{
95
 
   struct pipe_screen *screen = ctx->pipe->screen;
96
 
   if (memObj->memory)
97
 
      screen->memobj_destroy(screen, memObj->memory);
98
 
   FREE(memObj);
99
 
}
100
 
 
101
 
void GLAPIENTRY
102
 
_mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
103
 
{
104
 
   GET_CURRENT_CONTEXT(ctx);
105
 
 
106
 
   if (MESA_VERBOSE & (VERBOSE_API)) {
107
 
      _mesa_debug(ctx, "glDeleteMemoryObjectsEXT(%d, %p)\n", n,
108
 
                  memoryObjects);
109
 
   }
110
 
 
111
 
   if (!ctx->Extensions.EXT_memory_object) {
112
 
      _mesa_error(ctx, GL_INVALID_OPERATION,
113
 
                  "glDeleteMemoryObjectsEXT(unsupported)");
114
 
      return;
115
 
   }
116
 
 
117
 
   if (n < 0) {
118
 
      _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteMemoryObjectsEXT(n < 0)");
119
 
      return;
120
 
   }
121
 
 
122
 
   if (!memoryObjects)
123
 
      return;
124
 
 
125
 
   _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
126
 
   for (GLint i = 0; i < n; i++) {
127
 
      if (memoryObjects[i] > 0) {
128
 
         struct gl_memory_object *delObj
129
 
            = _mesa_lookup_memory_object_locked(ctx, memoryObjects[i]);
130
 
 
131
 
         if (delObj) {
132
 
            _mesa_HashRemoveLocked(ctx->Shared->MemoryObjects,
133
 
                                   memoryObjects[i]);
134
 
            _mesa_delete_memory_object(ctx, delObj);
135
 
         }
136
 
      }
137
 
   }
138
 
   _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
139
 
}
140
 
 
141
 
GLboolean GLAPIENTRY
142
 
_mesa_IsMemoryObjectEXT(GLuint memoryObject)
143
 
{
144
 
   GET_CURRENT_CONTEXT(ctx);
145
 
 
146
 
   if (!ctx->Extensions.EXT_memory_object) {
147
 
      _mesa_error(ctx, GL_INVALID_OPERATION,
148
 
                  "glIsMemoryObjectEXT(unsupported)");
149
 
      return GL_FALSE;
150
 
   }
151
 
 
152
 
   struct gl_memory_object *obj =
153
 
      _mesa_lookup_memory_object(ctx, memoryObject);
154
 
 
155
 
   return obj ? GL_TRUE : GL_FALSE;
156
 
}
157
 
 
158
 
void GLAPIENTRY
159
 
_mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
160
 
{
161
 
   GET_CURRENT_CONTEXT(ctx);
162
 
 
163
 
   const char *func = "glCreateMemoryObjectsEXT";
164
 
 
165
 
   if (MESA_VERBOSE & (VERBOSE_API))
166
 
      _mesa_debug(ctx, "%s(%d, %p)", func, n, memoryObjects);
167
 
 
168
 
   if (!ctx->Extensions.EXT_memory_object) {
169
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
170
 
      return;
171
 
   }
172
 
 
173
 
   if (n < 0) {
174
 
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
175
 
      return;
176
 
   }
177
 
 
178
 
   if (!memoryObjects)
179
 
      return;
180
 
 
181
 
   _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
182
 
   if (_mesa_HashFindFreeKeys(ctx->Shared->MemoryObjects, memoryObjects, n)) {
183
 
      for (GLsizei i = 0; i < n; i++) {
184
 
         struct gl_memory_object *memObj;
185
 
 
186
 
         /* allocate memory object */
187
 
         memObj = memoryobj_alloc(ctx, memoryObjects[i]);
188
 
         if (!memObj) {
189
 
            _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
190
 
            _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
191
 
            return;
192
 
         }
193
 
 
194
 
         /* insert into hash table */
195
 
         _mesa_HashInsertLocked(ctx->Shared->MemoryObjects,
196
 
                                memoryObjects[i],
197
 
                                memObj, true);
198
 
      }
199
 
   }
200
 
 
201
 
   _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
202
 
}
203
 
 
204
 
void GLAPIENTRY
205
 
_mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
206
 
                                 GLenum pname,
207
 
                                 const GLint *params)
208
 
{
209
 
   GET_CURRENT_CONTEXT(ctx);
210
 
   struct gl_memory_object *memObj;
211
 
 
212
 
   const char *func = "glMemoryObjectParameterivEXT";
213
 
 
214
 
   if (!ctx->Extensions.EXT_memory_object) {
215
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
216
 
      return;
217
 
   }
218
 
 
219
 
   memObj = _mesa_lookup_memory_object(ctx, memoryObject);
220
 
   if (!memObj)
221
 
      return;
222
 
 
223
 
   if (memObj->Immutable) {
224
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(memoryObject is immutable", func);
225
 
      return;
226
 
   }
227
 
 
228
 
   switch (pname) {
229
 
   case GL_DEDICATED_MEMORY_OBJECT_EXT:
230
 
      memObj->Dedicated = (GLboolean) params[0];
231
 
      break;
232
 
   case GL_PROTECTED_MEMORY_OBJECT_EXT:
233
 
      /* EXT_protected_textures not supported */
234
 
      goto invalid_pname;
235
 
   default:
236
 
      goto invalid_pname;
237
 
   }
238
 
   return;
239
 
 
240
 
invalid_pname:
241
 
   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
242
 
}
243
 
 
244
 
void GLAPIENTRY
245
 
_mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
246
 
                                    GLenum pname,
247
 
                                    GLint *params)
248
 
{
249
 
   GET_CURRENT_CONTEXT(ctx);
250
 
   struct gl_memory_object *memObj;
251
 
 
252
 
   const char *func = "glMemoryObjectParameterivEXT";
253
 
 
254
 
   if (!ctx->Extensions.EXT_memory_object) {
255
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
256
 
      return;
257
 
   }
258
 
 
259
 
   memObj = _mesa_lookup_memory_object(ctx, memoryObject);
260
 
   if (!memObj)
261
 
      return;
262
 
 
263
 
   switch (pname) {
264
 
      case GL_DEDICATED_MEMORY_OBJECT_EXT:
265
 
         *params = (GLint) memObj->Dedicated;
266
 
         break;
267
 
      case GL_PROTECTED_MEMORY_OBJECT_EXT:
268
 
         /* EXT_protected_textures not supported */
269
 
         goto invalid_pname;
270
 
      default:
271
 
         goto invalid_pname;
272
 
   }
273
 
   return;
274
 
 
275
 
invalid_pname:
276
 
   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
277
 
}
278
 
 
279
 
static struct gl_memory_object *
280
 
lookup_memory_object_err(struct gl_context *ctx, unsigned memory,
281
 
                         const char* func)
282
 
{
283
 
   if (memory == 0) {
284
 
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
285
 
      return NULL;
286
 
   }
287
 
 
288
 
   struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
289
 
   if (!memObj)
290
 
      return NULL;
291
 
 
292
 
   if (!memObj->Immutable) {
293
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
294
 
                  func);
295
 
      return NULL;
296
 
   }
297
 
 
298
 
   return memObj;
299
 
}
300
 
 
301
 
/**
302
 
 * Helper used by _mesa_TexStorageMem1/2/3DEXT().
303
 
 */
304
 
static void
305
 
texstorage_memory(GLuint dims, GLenum target, GLsizei levels,
306
 
                  GLenum internalFormat, GLsizei width, GLsizei height,
307
 
                  GLsizei depth, GLuint memory, GLuint64 offset,
308
 
                  const char *func)
309
 
{
310
 
   struct gl_texture_object *texObj;
311
 
   struct gl_memory_object *memObj;
312
 
 
313
 
   GET_CURRENT_CONTEXT(ctx);
314
 
 
315
 
   if (!ctx->Extensions.EXT_memory_object) {
316
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
317
 
      return;
318
 
   }
319
 
 
320
 
   if (!_mesa_is_legal_tex_storage_target(ctx, dims, target)) {
321
 
      _mesa_error(ctx, GL_INVALID_ENUM,
322
 
                  "%s(illegal target=%s)",
323
 
                  func, _mesa_enum_to_string(target));
324
 
      return;
325
 
   }
326
 
 
327
 
   /* Check the format to make sure it is sized. */
328
 
   if (!_mesa_is_legal_tex_storage_format(ctx, internalFormat)) {
329
 
      _mesa_error(ctx, GL_INVALID_ENUM,
330
 
                  "%s(internalformat = %s)", func,
331
 
                  _mesa_enum_to_string(internalFormat));
332
 
      return;
333
 
   }
334
 
 
335
 
   texObj = _mesa_get_current_tex_object(ctx, target);
336
 
   if (!texObj)
337
 
      return;
338
 
 
339
 
   memObj = lookup_memory_object_err(ctx, memory, func);
340
 
   if (!memObj)
341
 
      return;
342
 
 
343
 
   _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
344
 
                                levels, internalFormat,
345
 
                                width, height, depth, offset, false);
346
 
}
347
 
 
348
 
static void
349
 
texstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
350
 
                     GLenum internalFormat, GLsizei width, GLsizei height,
351
 
                     GLsizei depth, GLboolean fixedSampleLocations,
352
 
                     GLuint memory, GLuint64 offset, const char* func)
353
 
{
354
 
   struct gl_texture_object *texObj;
355
 
   struct gl_memory_object *memObj;
356
 
 
357
 
   GET_CURRENT_CONTEXT(ctx);
358
 
 
359
 
   if (!ctx->Extensions.EXT_memory_object) {
360
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
361
 
      return;
362
 
   }
363
 
 
364
 
   texObj = _mesa_get_current_tex_object(ctx, target);
365
 
   if (!texObj)
366
 
      return;
367
 
 
368
 
   memObj = lookup_memory_object_err(ctx, memory, func);
369
 
   if (!memObj)
370
 
      return;
371
 
 
372
 
   _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, target, samples,
373
 
                                   internalFormat, width, height, depth,
374
 
                                   fixedSampleLocations, offset, func);
375
 
}
376
 
 
377
 
/**
378
 
 * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
379
 
 */
380
 
static void
381
 
texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
382
 
                      GLenum internalFormat, GLsizei width, GLsizei height,
383
 
                      GLsizei depth, GLuint memory, GLuint64 offset,
384
 
                      const char *func)
385
 
{
386
 
   struct gl_texture_object *texObj;
387
 
   struct gl_memory_object *memObj;
388
 
 
389
 
   GET_CURRENT_CONTEXT(ctx);
390
 
 
391
 
   if (!ctx->Extensions.EXT_memory_object) {
392
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
393
 
      return;
394
 
   }
395
 
 
396
 
   /* Check the format to make sure it is sized. */
397
 
   if (!_mesa_is_legal_tex_storage_format(ctx, internalFormat)) {
398
 
      _mesa_error(ctx, GL_INVALID_ENUM,
399
 
                  "%s(internalformat = %s)", func,
400
 
                  _mesa_enum_to_string(internalFormat));
401
 
      return;
402
 
   }
403
 
 
404
 
   texObj = _mesa_lookup_texture(ctx, texture);
405
 
   if (!texObj)
406
 
      return;
407
 
 
408
 
   if (!_mesa_is_legal_tex_storage_target(ctx, dims, texObj->Target)) {
409
 
      _mesa_error(ctx, GL_INVALID_OPERATION,
410
 
                  "%s(illegal target=%s)", func,
411
 
                  _mesa_enum_to_string(texObj->Target));
412
 
      return;
413
 
   }
414
 
 
415
 
   memObj = lookup_memory_object_err(ctx, memory, func);
416
 
   if (!memObj)
417
 
      return;
418
 
 
419
 
   _mesa_texture_storage_memory(ctx, dims, texObj, memObj, texObj->Target,
420
 
                                levels, internalFormat,
421
 
                                width, height, depth, offset, true);
422
 
}
423
 
 
424
 
static void
425
 
texturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
426
 
                         GLenum internalFormat, GLsizei width, GLsizei height,
427
 
                         GLsizei depth, GLboolean fixedSampleLocations,
428
 
                         GLuint memory, GLuint64 offset, const char* func)
429
 
{
430
 
   struct gl_texture_object *texObj;
431
 
   struct gl_memory_object *memObj;
432
 
 
433
 
   GET_CURRENT_CONTEXT(ctx);
434
 
 
435
 
   if (!ctx->Extensions.EXT_memory_object) {
436
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
437
 
      return;
438
 
   }
439
 
 
440
 
   texObj = _mesa_lookup_texture(ctx, texture);
441
 
   if (!texObj)
442
 
      return;
443
 
 
444
 
   memObj = lookup_memory_object_err(ctx, memory, func);
445
 
   if (!memObj)
446
 
      return;
447
 
 
448
 
   _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, texObj->Target,
449
 
                                   samples, internalFormat, width, height,
450
 
                                   depth, fixedSampleLocations, offset, func);
451
 
}
452
 
 
453
 
void GLAPIENTRY
454
 
_mesa_TexStorageMem2DEXT(GLenum target,
455
 
                         GLsizei levels,
456
 
                         GLenum internalFormat,
457
 
                         GLsizei width,
458
 
                         GLsizei height,
459
 
                         GLuint memory,
460
 
                         GLuint64 offset)
461
 
{
462
 
   texstorage_memory(2, target, levels, internalFormat, width, height, 1,
463
 
                     memory, offset, "glTexStorageMem2DEXT");
464
 
}
465
 
 
466
 
void GLAPIENTRY
467
 
_mesa_TexStorageMem2DMultisampleEXT(GLenum target,
468
 
                                    GLsizei samples,
469
 
                                    GLenum internalFormat,
470
 
                                    GLsizei width,
471
 
                                    GLsizei height,
472
 
                                    GLboolean fixedSampleLocations,
473
 
                                    GLuint memory,
474
 
                                    GLuint64 offset)
475
 
{
476
 
   texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
477
 
                        fixedSampleLocations, memory, offset,
478
 
                        "glTexStorageMem2DMultisampleEXT");
479
 
}
480
 
 
481
 
void GLAPIENTRY
482
 
_mesa_TexStorageMem3DEXT(GLenum target,
483
 
                         GLsizei levels,
484
 
                         GLenum internalFormat,
485
 
                         GLsizei width,
486
 
                         GLsizei height,
487
 
                         GLsizei depth,
488
 
                         GLuint memory,
489
 
                         GLuint64 offset)
490
 
{
491
 
   texstorage_memory(3, target, levels, internalFormat, width, height, depth,
492
 
                     memory, offset, "glTexStorageMem3DEXT");
493
 
}
494
 
 
495
 
void GLAPIENTRY
496
 
_mesa_TexStorageMem3DMultisampleEXT(GLenum target,
497
 
                                    GLsizei samples,
498
 
                                    GLenum internalFormat,
499
 
                                    GLsizei width,
500
 
                                    GLsizei height,
501
 
                                    GLsizei depth,
502
 
                                    GLboolean fixedSampleLocations,
503
 
                                    GLuint memory,
504
 
                                    GLuint64 offset)
505
 
{
506
 
   texstorage_memory_ms(3, target, samples, internalFormat, width, height,
507
 
                        depth, fixedSampleLocations, memory, offset,
508
 
                        "glTexStorageMem3DMultisampleEXT");
509
 
}
510
 
 
511
 
void GLAPIENTRY
512
 
_mesa_TextureStorageMem2DEXT(GLuint texture,
513
 
                             GLsizei levels,
514
 
                             GLenum internalFormat,
515
 
                             GLsizei width,
516
 
                             GLsizei height,
517
 
                             GLuint memory,
518
 
                             GLuint64 offset)
519
 
{
520
 
   texturestorage_memory(2, texture, levels, internalFormat, width, height, 1,
521
 
                         memory, offset, "glTexureStorageMem2DEXT");
522
 
}
523
 
 
524
 
void GLAPIENTRY
525
 
_mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
526
 
                                        GLsizei samples,
527
 
                                        GLenum internalFormat,
528
 
                                        GLsizei width,
529
 
                                        GLsizei height,
530
 
                                        GLboolean fixedSampleLocations,
531
 
                                        GLuint memory,
532
 
                                        GLuint64 offset)
533
 
{
534
 
   texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
535
 
                            1, fixedSampleLocations, memory, offset,
536
 
                            "glTextureStorageMem2DMultisampleEXT");
537
 
}
538
 
 
539
 
void GLAPIENTRY
540
 
_mesa_TextureStorageMem3DEXT(GLuint texture,
541
 
                             GLsizei levels,
542
 
                             GLenum internalFormat,
543
 
                             GLsizei width,
544
 
                             GLsizei height,
545
 
                             GLsizei depth,
546
 
                             GLuint memory,
547
 
                             GLuint64 offset)
548
 
{
549
 
   texturestorage_memory(3, texture, levels, internalFormat, width, height,
550
 
                         depth, memory, offset, "glTextureStorageMem3DEXT");
551
 
}
552
 
 
553
 
void GLAPIENTRY
554
 
_mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
555
 
                                        GLsizei samples,
556
 
                                        GLenum internalFormat,
557
 
                                        GLsizei width,
558
 
                                        GLsizei height,
559
 
                                        GLsizei depth,
560
 
                                        GLboolean fixedSampleLocations,
561
 
                                        GLuint memory,
562
 
                                        GLuint64 offset)
563
 
{
564
 
   texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
565
 
                            depth, fixedSampleLocations, memory, offset,
566
 
                            "glTextureStorageMem3DMultisampleEXT");
567
 
}
568
 
 
569
 
void GLAPIENTRY
570
 
_mesa_TexStorageMem1DEXT(GLenum target,
571
 
                         GLsizei levels,
572
 
                         GLenum internalFormat,
573
 
                         GLsizei width,
574
 
                         GLuint memory,
575
 
                         GLuint64 offset)
576
 
{
577
 
   texstorage_memory(1, target, levels, internalFormat, width, 1, 1, memory,
578
 
                     offset, "glTexStorageMem1DEXT");
579
 
}
580
 
 
581
 
void GLAPIENTRY
582
 
_mesa_TextureStorageMem1DEXT(GLuint texture,
583
 
                             GLsizei levels,
584
 
                             GLenum internalFormat,
585
 
                             GLsizei width,
586
 
                             GLuint memory,
587
 
                             GLuint64 offset)
588
 
{
589
 
   texturestorage_memory(1, texture, levels, internalFormat, width, 1, 1,
590
 
                         memory, offset, "glTextureStorageMem1DEXT");
591
 
}
592
 
 
593
 
static struct gl_semaphore_object *
594
 
semaphoreobj_alloc(struct gl_context *ctx, GLuint name)
595
 
{
596
 
   struct gl_semaphore_object *obj = CALLOC_STRUCT(gl_semaphore_object);
597
 
   if (!obj)
598
 
      return NULL;
599
 
 
600
 
   obj->Name = name;
601
 
   return obj;
602
 
}
603
 
 
604
 
static void
605
 
import_semaphoreobj_fd(struct gl_context *ctx,
606
 
                          struct gl_semaphore_object *semObj,
607
 
                          int fd)
608
 
{
609
 
   struct pipe_context *pipe = ctx->pipe;
610
 
 
611
 
   pipe->create_fence_fd(pipe, &semObj->fence, fd, PIPE_FD_TYPE_SYNCOBJ);
612
 
 
613
 
#if !defined(_WIN32)
614
 
   /* We own fd, but we no longer need it. So get rid of it */
615
 
   close(fd);
616
 
#endif
617
 
}
618
 
 
619
 
static void
620
 
server_wait_semaphore(struct gl_context *ctx,
621
 
                      struct gl_semaphore_object *semObj,
622
 
                      GLuint numBufferBarriers,
623
 
                      struct gl_buffer_object **bufObjs,
624
 
                      GLuint numTextureBarriers,
625
 
                      struct gl_texture_object **texObjs,
626
 
                      const GLenum *srcLayouts)
627
 
{
628
 
   struct st_context *st = ctx->st;
629
 
   struct pipe_context *pipe = ctx->pipe;
630
 
   struct gl_buffer_object *bufObj;
631
 
   struct gl_texture_object *texObj;
632
 
 
633
 
   /* The driver is allowed to flush during fence_server_sync, be prepared */
634
 
   st_flush_bitmap_cache(st);
635
 
   pipe->fence_server_sync(pipe, semObj->fence);
636
 
 
637
 
   /**
638
 
    * According to the EXT_external_objects spec, the memory operations must
639
 
    * follow the wait. This is to make sure the flush is executed after the
640
 
    * other party is done modifying the memory.
641
 
    *
642
 
    * Relevant excerpt from section "4.2.3 Waiting for Semaphores":
643
 
    *
644
 
    * Following completion of the semaphore wait operation, memory will also be
645
 
    * made visible in the specified buffer and texture objects.
646
 
    *
647
 
    */
648
 
   for (unsigned i = 0; i < numBufferBarriers; i++) {
649
 
      if (!bufObjs[i])
650
 
         continue;
651
 
 
652
 
      bufObj = bufObjs[i];
653
 
      if (bufObj->buffer)
654
 
         pipe->flush_resource(pipe, bufObj->buffer);
655
 
   }
656
 
 
657
 
   for (unsigned i = 0; i < numTextureBarriers; i++) {
658
 
      if (!texObjs[i])
659
 
         continue;
660
 
 
661
 
      texObj = texObjs[i];
662
 
      if (texObj->pt)
663
 
         pipe->flush_resource(pipe, texObj->pt);
664
 
   }
665
 
}
666
 
 
667
 
static void
668
 
server_signal_semaphore(struct gl_context *ctx,
669
 
                        struct gl_semaphore_object *semObj,
670
 
                        GLuint numBufferBarriers,
671
 
                        struct gl_buffer_object **bufObjs,
672
 
                        GLuint numTextureBarriers,
673
 
                        struct gl_texture_object **texObjs,
674
 
                        const GLenum *dstLayouts)
675
 
{
676
 
   struct st_context *st = ctx->st;
677
 
   struct pipe_context *pipe = ctx->pipe;
678
 
   struct gl_buffer_object *bufObj;
679
 
   struct gl_texture_object *texObj;
680
 
 
681
 
   for (unsigned i = 0; i < numBufferBarriers; i++) {
682
 
      if (!bufObjs[i])
683
 
         continue;
684
 
 
685
 
      bufObj = bufObjs[i];
686
 
      if (bufObj->buffer)
687
 
         pipe->flush_resource(pipe, bufObj->buffer);
688
 
   }
689
 
 
690
 
   for (unsigned i = 0; i < numTextureBarriers; i++) {
691
 
      if (!texObjs[i])
692
 
         continue;
693
 
 
694
 
      texObj = texObjs[i];
695
 
      if (texObj->pt)
696
 
         pipe->flush_resource(pipe, texObj->pt);
697
 
   }
698
 
 
699
 
   /* The driver is allowed to flush during fence_server_signal, be prepared */
700
 
   st_flush_bitmap_cache(st);
701
 
   pipe->fence_server_signal(pipe, semObj->fence);
702
 
}
703
 
 
704
 
/**
705
 
 * Used as a placeholder for semaphore objects between glGenSemaphoresEXT()
706
 
 * and glImportSemaphoreFdEXT(), so that glIsSemaphoreEXT() can work correctly.
707
 
 */
708
 
static struct gl_semaphore_object DummySemaphoreObject;
709
 
 
710
 
/**
711
 
 * Delete a semaphore object.
712
 
 * Not removed from hash table here.
713
 
 */
714
 
void
715
 
_mesa_delete_semaphore_object(struct gl_context *ctx,
716
 
                              struct gl_semaphore_object *semObj)
717
 
{
718
 
   if (semObj != &DummySemaphoreObject)
719
 
      FREE(semObj);
720
 
}
721
 
 
722
 
void GLAPIENTRY
723
 
_mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
724
 
{
725
 
   GET_CURRENT_CONTEXT(ctx);
726
 
 
727
 
   const char *func = "glGenSemaphoresEXT";
728
 
 
729
 
   if (MESA_VERBOSE & (VERBOSE_API))
730
 
      _mesa_debug(ctx, "%s(%d, %p)", func, n, semaphores);
731
 
 
732
 
   if (!ctx->Extensions.EXT_semaphore) {
733
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
734
 
      return;
735
 
   }
736
 
 
737
 
   if (n < 0) {
738
 
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
739
 
      return;
740
 
   }
741
 
 
742
 
   if (!semaphores)
743
 
      return;
744
 
 
745
 
   _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects);
746
 
   if (_mesa_HashFindFreeKeys(ctx->Shared->SemaphoreObjects, semaphores, n)) {
747
 
      for (GLsizei i = 0; i < n; i++) {
748
 
         _mesa_HashInsertLocked(ctx->Shared->SemaphoreObjects,
749
 
                                semaphores[i], &DummySemaphoreObject, true);
750
 
      }
751
 
   }
752
 
 
753
 
   _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects);
754
 
}
755
 
 
756
 
void GLAPIENTRY
757
 
_mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
758
 
{
759
 
   GET_CURRENT_CONTEXT(ctx);
760
 
 
761
 
   const char *func = "glDeleteSemaphoresEXT";
762
 
 
763
 
   if (MESA_VERBOSE & (VERBOSE_API)) {
764
 
      _mesa_debug(ctx, "%s(%d, %p)\n", func, n, semaphores);
765
 
   }
766
 
 
767
 
   if (!ctx->Extensions.EXT_semaphore) {
768
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
769
 
      return;
770
 
   }
771
 
 
772
 
   if (n < 0) {
773
 
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
774
 
      return;
775
 
   }
776
 
 
777
 
   if (!semaphores)
778
 
      return;
779
 
 
780
 
   _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects);
781
 
   for (GLint i = 0; i < n; i++) {
782
 
      if (semaphores[i] > 0) {
783
 
         struct gl_semaphore_object *delObj
784
 
            = _mesa_lookup_semaphore_object_locked(ctx, semaphores[i]);
785
 
 
786
 
         if (delObj) {
787
 
            _mesa_HashRemoveLocked(ctx->Shared->SemaphoreObjects,
788
 
                                   semaphores[i]);
789
 
            _mesa_delete_semaphore_object(ctx, delObj);
790
 
         }
791
 
      }
792
 
   }
793
 
   _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects);
794
 
}
795
 
 
796
 
GLboolean GLAPIENTRY
797
 
_mesa_IsSemaphoreEXT(GLuint semaphore)
798
 
{
799
 
   GET_CURRENT_CONTEXT(ctx);
800
 
 
801
 
   if (!ctx->Extensions.EXT_semaphore) {
802
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "glIsSemaphoreEXT(unsupported)");
803
 
      return GL_FALSE;
804
 
   }
805
 
 
806
 
   struct gl_semaphore_object *obj =
807
 
      _mesa_lookup_semaphore_object(ctx, semaphore);
808
 
 
809
 
   return obj ? GL_TRUE : GL_FALSE;
810
 
}
811
 
 
812
 
/**
813
 
 * Helper that outputs the correct error status for parameter
814
 
 * calls where no pnames are defined
815
 
 */
816
 
static void
817
 
semaphore_parameter_stub(const char* func, GLenum pname)
818
 
{
819
 
   GET_CURRENT_CONTEXT(ctx);
820
 
 
821
 
   if (!ctx->Extensions.EXT_semaphore) {
822
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
823
 
      return;
824
 
   }
825
 
 
826
 
   /* EXT_semaphore and EXT_semaphore_fd define no parameters */
827
 
   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
828
 
}
829
 
 
830
 
void GLAPIENTRY
831
 
_mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
832
 
                                 GLenum pname,
833
 
                                 const GLuint64 *params)
834
 
{
835
 
   const char *func = "glSemaphoreParameterui64vEXT";
836
 
 
837
 
   semaphore_parameter_stub(func, pname);
838
 
}
839
 
 
840
 
void GLAPIENTRY
841
 
_mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,
842
 
                                    GLenum pname,
843
 
                                    GLuint64 *params)
844
 
{
845
 
   const char *func = "glGetSemaphoreParameterui64vEXT";
846
 
 
847
 
   semaphore_parameter_stub(func, pname);
848
 
}
849
 
 
850
 
void GLAPIENTRY
851
 
_mesa_WaitSemaphoreEXT(GLuint semaphore,
852
 
                       GLuint numBufferBarriers,
853
 
                       const GLuint *buffers,
854
 
                       GLuint numTextureBarriers,
855
 
                       const GLuint *textures,
856
 
                       const GLenum *srcLayouts)
857
 
{
858
 
   GET_CURRENT_CONTEXT(ctx);
859
 
   struct gl_semaphore_object *semObj = NULL;
860
 
   struct gl_buffer_object **bufObjs = NULL;
861
 
   struct gl_texture_object **texObjs = NULL;
862
 
 
863
 
   const char *func = "glWaitSemaphoreEXT";
864
 
 
865
 
   if (!ctx->Extensions.EXT_semaphore) {
866
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
867
 
      return;
868
 
   }
869
 
 
870
 
   ASSERT_OUTSIDE_BEGIN_END(ctx);
871
 
 
872
 
   semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
873
 
   if (!semObj)
874
 
      return;
875
 
 
876
 
   FLUSH_VERTICES(ctx, 0, 0);
877
 
 
878
 
   bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
879
 
   if (!bufObjs) {
880
 
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
881
 
                  func, numBufferBarriers);
882
 
      goto end;
883
 
   }
884
 
 
885
 
   for (unsigned i = 0; i < numBufferBarriers; i++) {
886
 
      bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
887
 
   }
888
 
 
889
 
   texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
890
 
   if (!texObjs) {
891
 
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
892
 
                  func, numTextureBarriers);
893
 
      goto end;
894
 
   }
895
 
 
896
 
   for (unsigned i = 0; i < numTextureBarriers; i++) {
897
 
      texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
898
 
   }
899
 
 
900
 
   server_wait_semaphore(ctx, semObj,
901
 
                         numBufferBarriers, bufObjs,
902
 
                         numTextureBarriers, texObjs,
903
 
                         srcLayouts);
904
 
 
905
 
end:
906
 
   free(bufObjs);
907
 
   free(texObjs);
908
 
}
909
 
 
910
 
void GLAPIENTRY
911
 
_mesa_SignalSemaphoreEXT(GLuint semaphore,
912
 
                         GLuint numBufferBarriers,
913
 
                         const GLuint *buffers,
914
 
                         GLuint numTextureBarriers,
915
 
                         const GLuint *textures,
916
 
                         const GLenum *dstLayouts)
917
 
{
918
 
   GET_CURRENT_CONTEXT(ctx);
919
 
   struct gl_semaphore_object *semObj = NULL;
920
 
   struct gl_buffer_object **bufObjs = NULL;
921
 
   struct gl_texture_object **texObjs = NULL;
922
 
 
923
 
   const char *func = "glSignalSemaphoreEXT";
924
 
 
925
 
   if (!ctx->Extensions.EXT_semaphore) {
926
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
927
 
      return;
928
 
   }
929
 
 
930
 
   ASSERT_OUTSIDE_BEGIN_END(ctx);
931
 
 
932
 
   semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
933
 
   if (!semObj)
934
 
      return;
935
 
 
936
 
   FLUSH_VERTICES(ctx, 0, 0);
937
 
 
938
 
   bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
939
 
   if (!bufObjs) {
940
 
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
941
 
                  func, numBufferBarriers);
942
 
      goto end;
943
 
   }
944
 
 
945
 
   for (unsigned i = 0; i < numBufferBarriers; i++) {
946
 
      bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
947
 
   }
948
 
 
949
 
   texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
950
 
   if (!texObjs) {
951
 
      _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
952
 
                  func, numTextureBarriers);
953
 
      goto end;
954
 
   }
955
 
 
956
 
   for (unsigned i = 0; i < numTextureBarriers; i++) {
957
 
      texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
958
 
   }
959
 
 
960
 
   server_signal_semaphore(ctx, semObj,
961
 
                           numBufferBarriers, bufObjs,
962
 
                           numTextureBarriers, texObjs,
963
 
                           dstLayouts);
964
 
 
965
 
end:
966
 
   free(bufObjs);
967
 
   free(texObjs);
968
 
}
969
 
 
970
 
void GLAPIENTRY
971
 
_mesa_ImportMemoryFdEXT(GLuint memory,
972
 
                        GLuint64 size,
973
 
                        GLenum handleType,
974
 
                        GLint fd)
975
 
{
976
 
   GET_CURRENT_CONTEXT(ctx);
977
 
 
978
 
   const char *func = "glImportMemoryFdEXT";
979
 
 
980
 
   if (!ctx->Extensions.EXT_memory_object_fd) {
981
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
982
 
      return;
983
 
   }
984
 
 
985
 
   if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
986
 
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
987
 
      return;
988
 
   }
989
 
 
990
 
   struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
991
 
   if (!memObj)
992
 
      return;
993
 
 
994
 
   import_memoryobj_fd(ctx, memObj, size, fd);
995
 
   memObj->Immutable = GL_TRUE;
996
 
}
997
 
 
998
 
void GLAPIENTRY
999
 
_mesa_ImportSemaphoreFdEXT(GLuint semaphore,
1000
 
                           GLenum handleType,
1001
 
                           GLint fd)
1002
 
{
1003
 
   GET_CURRENT_CONTEXT(ctx);
1004
 
 
1005
 
   const char *func = "glImportSemaphoreFdEXT";
1006
 
 
1007
 
   if (!ctx->Extensions.EXT_semaphore_fd) {
1008
 
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
1009
 
      return;
1010
 
   }
1011
 
 
1012
 
   if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
1013
 
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
1014
 
      return;
1015
 
   }
1016
 
 
1017
 
   struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx,
1018
 
                                                                      semaphore);
1019
 
   if (!semObj)
1020
 
      return;
1021
 
 
1022
 
   if (semObj == &DummySemaphoreObject) {
1023
 
      semObj = semaphoreobj_alloc(ctx, semaphore);
1024
 
      if (!semObj) {
1025
 
         _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
1026
 
         return;
1027
 
      }
1028
 
      _mesa_HashInsert(ctx->Shared->SemaphoreObjects, semaphore, semObj, true);
1029
 
   }
1030
 
 
1031
 
   import_semaphoreobj_fd(ctx, semObj, fd);
1032
 
}