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 *
memoryobj_alloc(struct gl_context * ctx,GLuint name)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
import_memoryobj_fd(struct gl_context * ctx,struct gl_memory_object * obj,GLuint64 size,int fd)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 static void
import_memoryobj_win32(struct gl_context * ctx,struct gl_memory_object * obj,GLuint64 size,void * handle,const void * name)88 import_memoryobj_win32(struct gl_context *ctx,
89 struct gl_memory_object *obj,
90 GLuint64 size,
91 void *handle,
92 const void *name)
93 {
94 struct pipe_screen *screen = ctx->pipe->screen;
95 struct winsys_handle whandle = {
96 .type = handle ? WINSYS_HANDLE_TYPE_WIN32_HANDLE : WINSYS_HANDLE_TYPE_WIN32_NAME,
97 #ifdef _WIN32
98 .handle = handle,
99 #else
100 .handle = 0,
101 #endif
102 #ifdef HAVE_LIBDRM
103 .modifier = DRM_FORMAT_MOD_INVALID,
104 #endif
105 .name = name,
106 };
107
108 obj->memory = screen->memobj_create_from_handle(screen,
109 &whandle,
110 obj->Dedicated);
111 }
112
113 /**
114 * Delete a memory object.
115 * Not removed from hash table here.
116 */
117 void
_mesa_delete_memory_object(struct gl_context * ctx,struct gl_memory_object * memObj)118 _mesa_delete_memory_object(struct gl_context *ctx,
119 struct gl_memory_object *memObj)
120 {
121 struct pipe_screen *screen = ctx->pipe->screen;
122 if (memObj->memory)
123 screen->memobj_destroy(screen, memObj->memory);
124 FREE(memObj);
125 }
126
127 void GLAPIENTRY
_mesa_DeleteMemoryObjectsEXT(GLsizei n,const GLuint * memoryObjects)128 _mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
129 {
130 GET_CURRENT_CONTEXT(ctx);
131
132 if (MESA_VERBOSE & (VERBOSE_API)) {
133 _mesa_debug(ctx, "glDeleteMemoryObjectsEXT(%d, %p)\n", n,
134 memoryObjects);
135 }
136
137 if (!ctx->Extensions.EXT_memory_object) {
138 _mesa_error(ctx, GL_INVALID_OPERATION,
139 "glDeleteMemoryObjectsEXT(unsupported)");
140 return;
141 }
142
143 if (n < 0) {
144 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteMemoryObjectsEXT(n < 0)");
145 return;
146 }
147
148 if (!memoryObjects)
149 return;
150
151 _mesa_HashLockMutex(&ctx->Shared->MemoryObjects);
152 for (GLint i = 0; i < n; i++) {
153 if (memoryObjects[i] > 0) {
154 struct gl_memory_object *delObj
155 = _mesa_lookup_memory_object_locked(ctx, memoryObjects[i]);
156
157 if (delObj) {
158 _mesa_HashRemoveLocked(&ctx->Shared->MemoryObjects,
159 memoryObjects[i]);
160 _mesa_delete_memory_object(ctx, delObj);
161 }
162 }
163 }
164 _mesa_HashUnlockMutex(&ctx->Shared->MemoryObjects);
165 }
166
167 GLboolean GLAPIENTRY
_mesa_IsMemoryObjectEXT(GLuint memoryObject)168 _mesa_IsMemoryObjectEXT(GLuint memoryObject)
169 {
170 GET_CURRENT_CONTEXT(ctx);
171
172 if (!ctx->Extensions.EXT_memory_object) {
173 _mesa_error(ctx, GL_INVALID_OPERATION,
174 "glIsMemoryObjectEXT(unsupported)");
175 return GL_FALSE;
176 }
177
178 struct gl_memory_object *obj =
179 _mesa_lookup_memory_object(ctx, memoryObject);
180
181 return obj ? GL_TRUE : GL_FALSE;
182 }
183
184 void GLAPIENTRY
_mesa_CreateMemoryObjectsEXT(GLsizei n,GLuint * memoryObjects)185 _mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
186 {
187 GET_CURRENT_CONTEXT(ctx);
188
189 const char *func = "glCreateMemoryObjectsEXT";
190
191 if (MESA_VERBOSE & (VERBOSE_API))
192 _mesa_debug(ctx, "%s(%d, %p)\n", func, n, memoryObjects);
193
194 if (!ctx->Extensions.EXT_memory_object) {
195 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
196 return;
197 }
198
199 if (n < 0) {
200 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
201 return;
202 }
203
204 if (!memoryObjects)
205 return;
206
207 _mesa_HashLockMutex(&ctx->Shared->MemoryObjects);
208 if (_mesa_HashFindFreeKeys(&ctx->Shared->MemoryObjects, memoryObjects, n)) {
209 for (GLsizei i = 0; i < n; i++) {
210 struct gl_memory_object *memObj;
211
212 /* allocate memory object */
213 memObj = memoryobj_alloc(ctx, memoryObjects[i]);
214 if (!memObj) {
215 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
216 _mesa_HashUnlockMutex(&ctx->Shared->MemoryObjects);
217 return;
218 }
219
220 /* insert into hash table */
221 _mesa_HashInsertLocked(&ctx->Shared->MemoryObjects, memoryObjects[i],
222 memObj);
223 }
224 }
225
226 _mesa_HashUnlockMutex(&ctx->Shared->MemoryObjects);
227 }
228
229 void GLAPIENTRY
_mesa_MemoryObjectParameterivEXT(GLuint memoryObject,GLenum pname,const GLint * params)230 _mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
231 GLenum pname,
232 const GLint *params)
233 {
234 GET_CURRENT_CONTEXT(ctx);
235 struct gl_memory_object *memObj;
236
237 const char *func = "glMemoryObjectParameterivEXT";
238
239 if (!ctx->Extensions.EXT_memory_object) {
240 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
241 return;
242 }
243
244 memObj = _mesa_lookup_memory_object(ctx, memoryObject);
245 if (!memObj)
246 return;
247
248 if (memObj->Immutable) {
249 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(memoryObject is immutable", func);
250 return;
251 }
252
253 switch (pname) {
254 case GL_DEDICATED_MEMORY_OBJECT_EXT:
255 memObj->Dedicated = (GLboolean) params[0];
256 break;
257 case GL_PROTECTED_MEMORY_OBJECT_EXT:
258 /* EXT_protected_textures not supported */
259 goto invalid_pname;
260 default:
261 goto invalid_pname;
262 }
263 return;
264
265 invalid_pname:
266 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
267 }
268
269 void GLAPIENTRY
_mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,GLenum pname,GLint * params)270 _mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
271 GLenum pname,
272 GLint *params)
273 {
274 GET_CURRENT_CONTEXT(ctx);
275 struct gl_memory_object *memObj;
276
277 const char *func = "glMemoryObjectParameterivEXT";
278
279 if (!ctx->Extensions.EXT_memory_object) {
280 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
281 return;
282 }
283
284 memObj = _mesa_lookup_memory_object(ctx, memoryObject);
285 if (!memObj)
286 return;
287
288 switch (pname) {
289 case GL_DEDICATED_MEMORY_OBJECT_EXT:
290 *params = (GLint) memObj->Dedicated;
291 break;
292 case GL_PROTECTED_MEMORY_OBJECT_EXT:
293 /* EXT_protected_textures not supported */
294 goto invalid_pname;
295 default:
296 goto invalid_pname;
297 }
298 return;
299
300 invalid_pname:
301 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
302 }
303
304 static struct gl_memory_object *
lookup_memory_object_err(struct gl_context * ctx,unsigned memory,const char * func)305 lookup_memory_object_err(struct gl_context *ctx, unsigned memory,
306 const char* func)
307 {
308 if (memory == 0) {
309 _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
310 return NULL;
311 }
312
313 struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
314 if (!memObj)
315 return NULL;
316
317 if (!memObj->Immutable) {
318 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
319 func);
320 return NULL;
321 }
322
323 return memObj;
324 }
325
326 /**
327 * Helper used by _mesa_TexStorageMem1/2/3DEXT().
328 */
329 static void
texstorage_memory(GLuint dims,GLenum target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLuint memory,GLuint64 offset,const char * func)330 texstorage_memory(GLuint dims, GLenum target, GLsizei levels,
331 GLenum internalFormat, GLsizei width, GLsizei height,
332 GLsizei depth, GLuint memory, GLuint64 offset,
333 const char *func)
334 {
335 struct gl_texture_object *texObj;
336 struct gl_memory_object *memObj;
337
338 GET_CURRENT_CONTEXT(ctx);
339
340 if (!ctx->Extensions.EXT_memory_object) {
341 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
342 return;
343 }
344
345 if (!_mesa_is_legal_tex_storage_target(ctx, dims, target)) {
346 _mesa_error(ctx, GL_INVALID_ENUM,
347 "%s(illegal target=%s)",
348 func, _mesa_enum_to_string(target));
349 return;
350 }
351
352 /* Check the format to make sure it is sized. */
353 if (!_mesa_is_legal_tex_storage_format(ctx, internalFormat)) {
354 _mesa_error(ctx, GL_INVALID_ENUM,
355 "%s(internalformat = %s)", func,
356 _mesa_enum_to_string(internalFormat));
357 return;
358 }
359
360 texObj = _mesa_get_current_tex_object(ctx, target);
361 if (!texObj)
362 return;
363
364 memObj = lookup_memory_object_err(ctx, memory, func);
365 if (!memObj)
366 return;
367
368 _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
369 levels, internalFormat,
370 width, height, depth, offset, false);
371 }
372
373 static void
texstorage_memory_ms(GLuint dims,GLenum target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,GLuint memory,GLuint64 offset,const char * func)374 texstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
375 GLenum internalFormat, GLsizei width, GLsizei height,
376 GLsizei depth, GLboolean fixedSampleLocations,
377 GLuint memory, GLuint64 offset, const char* func)
378 {
379 struct gl_texture_object *texObj;
380 struct gl_memory_object *memObj;
381
382 GET_CURRENT_CONTEXT(ctx);
383
384 if (!ctx->Extensions.EXT_memory_object) {
385 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
386 return;
387 }
388
389 texObj = _mesa_get_current_tex_object(ctx, target);
390 if (!texObj)
391 return;
392
393 memObj = lookup_memory_object_err(ctx, memory, func);
394 if (!memObj)
395 return;
396
397 _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, target, samples,
398 internalFormat, width, height, depth,
399 fixedSampleLocations, offset, func);
400 }
401
402 /**
403 * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
404 */
405 static void
texturestorage_memory(GLuint dims,GLuint texture,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLuint memory,GLuint64 offset,const char * func)406 texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
407 GLenum internalFormat, GLsizei width, GLsizei height,
408 GLsizei depth, GLuint memory, GLuint64 offset,
409 const char *func)
410 {
411 struct gl_texture_object *texObj;
412 struct gl_memory_object *memObj;
413
414 GET_CURRENT_CONTEXT(ctx);
415
416 if (!ctx->Extensions.EXT_memory_object) {
417 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
418 return;
419 }
420
421 /* Check the format to make sure it is sized. */
422 if (!_mesa_is_legal_tex_storage_format(ctx, internalFormat)) {
423 _mesa_error(ctx, GL_INVALID_ENUM,
424 "%s(internalformat = %s)", func,
425 _mesa_enum_to_string(internalFormat));
426 return;
427 }
428
429 texObj = _mesa_lookup_texture(ctx, texture);
430 if (!texObj)
431 return;
432
433 if (!_mesa_is_legal_tex_storage_target(ctx, dims, texObj->Target)) {
434 _mesa_error(ctx, GL_INVALID_OPERATION,
435 "%s(illegal target=%s)", func,
436 _mesa_enum_to_string(texObj->Target));
437 return;
438 }
439
440 memObj = lookup_memory_object_err(ctx, memory, func);
441 if (!memObj)
442 return;
443
444 _mesa_texture_storage_memory(ctx, dims, texObj, memObj, texObj->Target,
445 levels, internalFormat,
446 width, height, depth, offset, true);
447 }
448
449 static void
texturestorage_memory_ms(GLuint dims,GLuint texture,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,GLuint memory,GLuint64 offset,const char * func)450 texturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
451 GLenum internalFormat, GLsizei width, GLsizei height,
452 GLsizei depth, GLboolean fixedSampleLocations,
453 GLuint memory, GLuint64 offset, const char* func)
454 {
455 struct gl_texture_object *texObj;
456 struct gl_memory_object *memObj;
457
458 GET_CURRENT_CONTEXT(ctx);
459
460 if (!ctx->Extensions.EXT_memory_object) {
461 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
462 return;
463 }
464
465 texObj = _mesa_lookup_texture(ctx, texture);
466 if (!texObj)
467 return;
468
469 memObj = lookup_memory_object_err(ctx, memory, func);
470 if (!memObj)
471 return;
472
473 _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, texObj->Target,
474 samples, internalFormat, width, height,
475 depth, fixedSampleLocations, offset, func);
476 }
477
478 void GLAPIENTRY
_mesa_TexStorageMem2DEXT(GLenum target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLuint memory,GLuint64 offset)479 _mesa_TexStorageMem2DEXT(GLenum target,
480 GLsizei levels,
481 GLenum internalFormat,
482 GLsizei width,
483 GLsizei height,
484 GLuint memory,
485 GLuint64 offset)
486 {
487 texstorage_memory(2, target, levels, internalFormat, width, height, 1,
488 memory, offset, "glTexStorageMem2DEXT");
489 }
490
491 void GLAPIENTRY
_mesa_TexStorageMem2DMultisampleEXT(GLenum target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,GLuint memory,GLuint64 offset)492 _mesa_TexStorageMem2DMultisampleEXT(GLenum target,
493 GLsizei samples,
494 GLenum internalFormat,
495 GLsizei width,
496 GLsizei height,
497 GLboolean fixedSampleLocations,
498 GLuint memory,
499 GLuint64 offset)
500 {
501 texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
502 fixedSampleLocations, memory, offset,
503 "glTexStorageMem2DMultisampleEXT");
504 }
505
506 void GLAPIENTRY
_mesa_TexStorageMem3DEXT(GLenum target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLuint memory,GLuint64 offset)507 _mesa_TexStorageMem3DEXT(GLenum target,
508 GLsizei levels,
509 GLenum internalFormat,
510 GLsizei width,
511 GLsizei height,
512 GLsizei depth,
513 GLuint memory,
514 GLuint64 offset)
515 {
516 texstorage_memory(3, target, levels, internalFormat, width, height, depth,
517 memory, offset, "glTexStorageMem3DEXT");
518 }
519
520 void GLAPIENTRY
_mesa_TexStorageMem3DMultisampleEXT(GLenum target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,GLuint memory,GLuint64 offset)521 _mesa_TexStorageMem3DMultisampleEXT(GLenum target,
522 GLsizei samples,
523 GLenum internalFormat,
524 GLsizei width,
525 GLsizei height,
526 GLsizei depth,
527 GLboolean fixedSampleLocations,
528 GLuint memory,
529 GLuint64 offset)
530 {
531 texstorage_memory_ms(3, target, samples, internalFormat, width, height,
532 depth, fixedSampleLocations, memory, offset,
533 "glTexStorageMem3DMultisampleEXT");
534 }
535
536 void GLAPIENTRY
_mesa_TextureStorageMem2DEXT(GLuint texture,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLuint memory,GLuint64 offset)537 _mesa_TextureStorageMem2DEXT(GLuint texture,
538 GLsizei levels,
539 GLenum internalFormat,
540 GLsizei width,
541 GLsizei height,
542 GLuint memory,
543 GLuint64 offset)
544 {
545 texturestorage_memory(2, texture, levels, internalFormat, width, height, 1,
546 memory, offset, "glTexureStorageMem2DEXT");
547 }
548
549 void GLAPIENTRY
_mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,GLuint memory,GLuint64 offset)550 _mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
551 GLsizei samples,
552 GLenum internalFormat,
553 GLsizei width,
554 GLsizei height,
555 GLboolean fixedSampleLocations,
556 GLuint memory,
557 GLuint64 offset)
558 {
559 texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
560 1, fixedSampleLocations, memory, offset,
561 "glTextureStorageMem2DMultisampleEXT");
562 }
563
564 void GLAPIENTRY
_mesa_TextureStorageMem3DEXT(GLuint texture,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLuint memory,GLuint64 offset)565 _mesa_TextureStorageMem3DEXT(GLuint texture,
566 GLsizei levels,
567 GLenum internalFormat,
568 GLsizei width,
569 GLsizei height,
570 GLsizei depth,
571 GLuint memory,
572 GLuint64 offset)
573 {
574 texturestorage_memory(3, texture, levels, internalFormat, width, height,
575 depth, memory, offset, "glTextureStorageMem3DEXT");
576 }
577
578 void GLAPIENTRY
_mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,GLuint memory,GLuint64 offset)579 _mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
580 GLsizei samples,
581 GLenum internalFormat,
582 GLsizei width,
583 GLsizei height,
584 GLsizei depth,
585 GLboolean fixedSampleLocations,
586 GLuint memory,
587 GLuint64 offset)
588 {
589 texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
590 depth, fixedSampleLocations, memory, offset,
591 "glTextureStorageMem3DMultisampleEXT");
592 }
593
594 void GLAPIENTRY
_mesa_TexStorageMem1DEXT(GLenum target,GLsizei levels,GLenum internalFormat,GLsizei width,GLuint memory,GLuint64 offset)595 _mesa_TexStorageMem1DEXT(GLenum target,
596 GLsizei levels,
597 GLenum internalFormat,
598 GLsizei width,
599 GLuint memory,
600 GLuint64 offset)
601 {
602 texstorage_memory(1, target, levels, internalFormat, width, 1, 1, memory,
603 offset, "glTexStorageMem1DEXT");
604 }
605
606 void GLAPIENTRY
_mesa_TextureStorageMem1DEXT(GLuint texture,GLsizei levels,GLenum internalFormat,GLsizei width,GLuint memory,GLuint64 offset)607 _mesa_TextureStorageMem1DEXT(GLuint texture,
608 GLsizei levels,
609 GLenum internalFormat,
610 GLsizei width,
611 GLuint memory,
612 GLuint64 offset)
613 {
614 texturestorage_memory(1, texture, levels, internalFormat, width, 1, 1,
615 memory, offset, "glTextureStorageMem1DEXT");
616 }
617
618 static struct gl_semaphore_object *
semaphoreobj_alloc(struct gl_context * ctx,GLuint name)619 semaphoreobj_alloc(struct gl_context *ctx, GLuint name)
620 {
621 struct gl_semaphore_object *obj = CALLOC_STRUCT(gl_semaphore_object);
622 if (!obj)
623 return NULL;
624
625 obj->Name = name;
626 return obj;
627 }
628
629 static void
import_semaphoreobj_fd(struct gl_context * ctx,struct gl_semaphore_object * semObj,int fd)630 import_semaphoreobj_fd(struct gl_context *ctx,
631 struct gl_semaphore_object *semObj,
632 int fd)
633 {
634 struct pipe_context *pipe = ctx->pipe;
635
636 pipe->create_fence_fd(pipe, &semObj->fence, fd, PIPE_FD_TYPE_SYNCOBJ);
637
638 #if !defined(_WIN32)
639 /* We own fd, but we no longer need it. So get rid of it */
640 close(fd);
641 #endif
642 }
643
644 static void
import_semaphoreobj_win32(struct gl_context * ctx,struct gl_semaphore_object * semObj,void * handle,const void * name,enum pipe_fd_type type)645 import_semaphoreobj_win32(struct gl_context *ctx,
646 struct gl_semaphore_object *semObj,
647 void *handle,
648 const void *name,
649 enum pipe_fd_type type)
650 {
651 struct pipe_context *pipe = ctx->pipe;
652 semObj->type = type;
653
654 pipe->screen->create_fence_win32(pipe->screen, &semObj->fence, handle, name, type);
655 }
656
657 static void
server_wait_semaphore(struct gl_context * ctx,struct gl_semaphore_object * semObj,GLuint numBufferBarriers,struct gl_buffer_object ** bufObjs,GLuint numTextureBarriers,struct gl_texture_object ** texObjs,const GLenum * srcLayouts)658 server_wait_semaphore(struct gl_context *ctx,
659 struct gl_semaphore_object *semObj,
660 GLuint numBufferBarriers,
661 struct gl_buffer_object **bufObjs,
662 GLuint numTextureBarriers,
663 struct gl_texture_object **texObjs,
664 const GLenum *srcLayouts)
665 {
666 struct st_context *st = ctx->st;
667 struct pipe_context *pipe = ctx->pipe;
668 struct gl_buffer_object *bufObj;
669 struct gl_texture_object *texObj;
670
671 /* The driver is allowed to flush during fence_server_sync, be prepared */
672 st_flush_bitmap_cache(st);
673 pipe->fence_server_sync(pipe, semObj->fence);
674
675 /**
676 * According to the EXT_external_objects spec, the memory operations must
677 * follow the wait. This is to make sure the flush is executed after the
678 * other party is done modifying the memory.
679 *
680 * Relevant excerpt from section "4.2.3 Waiting for Semaphores":
681 *
682 * Following completion of the semaphore wait operation, memory will also be
683 * made visible in the specified buffer and texture objects.
684 *
685 */
686 for (unsigned i = 0; i < numBufferBarriers; i++) {
687 if (!bufObjs[i])
688 continue;
689
690 bufObj = bufObjs[i];
691 if (bufObj->buffer)
692 pipe->flush_resource(pipe, bufObj->buffer);
693 }
694
695 for (unsigned i = 0; i < numTextureBarriers; i++) {
696 if (!texObjs[i])
697 continue;
698
699 texObj = texObjs[i];
700 if (texObj->pt)
701 pipe->flush_resource(pipe, texObj->pt);
702 }
703 }
704
705 static void
server_signal_semaphore(struct gl_context * ctx,struct gl_semaphore_object * semObj,GLuint numBufferBarriers,struct gl_buffer_object ** bufObjs,GLuint numTextureBarriers,struct gl_texture_object ** texObjs,const GLenum * dstLayouts)706 server_signal_semaphore(struct gl_context *ctx,
707 struct gl_semaphore_object *semObj,
708 GLuint numBufferBarriers,
709 struct gl_buffer_object **bufObjs,
710 GLuint numTextureBarriers,
711 struct gl_texture_object **texObjs,
712 const GLenum *dstLayouts)
713 {
714 struct st_context *st = ctx->st;
715 struct pipe_context *pipe = ctx->pipe;
716 struct gl_buffer_object *bufObj;
717 struct gl_texture_object *texObj;
718
719 for (unsigned i = 0; i < numBufferBarriers; i++) {
720 if (!bufObjs[i])
721 continue;
722
723 bufObj = bufObjs[i];
724 if (bufObj->buffer)
725 pipe->flush_resource(pipe, bufObj->buffer);
726 }
727
728 for (unsigned i = 0; i < numTextureBarriers; i++) {
729 if (!texObjs[i])
730 continue;
731
732 texObj = texObjs[i];
733 if (texObj->pt)
734 pipe->flush_resource(pipe, texObj->pt);
735 }
736
737 /* The driver must flush during fence_server_signal, be prepared */
738 st_flush_bitmap_cache(st);
739 pipe->fence_server_signal(pipe, semObj->fence);
740 }
741
742 /**
743 * Used as a placeholder for semaphore objects between glGenSemaphoresEXT()
744 * and glImportSemaphoreFdEXT(), so that glIsSemaphoreEXT() can work correctly.
745 */
746 static struct gl_semaphore_object DummySemaphoreObject;
747
748 /**
749 * Delete a semaphore object.
750 * Not removed from hash table here.
751 */
752 void
_mesa_delete_semaphore_object(struct gl_context * ctx,struct gl_semaphore_object * semObj)753 _mesa_delete_semaphore_object(struct gl_context *ctx,
754 struct gl_semaphore_object *semObj)
755 {
756 if (semObj != &DummySemaphoreObject) {
757 struct pipe_context *pipe = ctx->pipe;
758 pipe->screen->fence_reference(ctx->screen, &semObj->fence, NULL);
759 FREE(semObj);
760 }
761 }
762
763 void GLAPIENTRY
_mesa_GenSemaphoresEXT(GLsizei n,GLuint * semaphores)764 _mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
765 {
766 GET_CURRENT_CONTEXT(ctx);
767
768 const char *func = "glGenSemaphoresEXT";
769
770 if (MESA_VERBOSE & (VERBOSE_API))
771 _mesa_debug(ctx, "%s(%d, %p)\n", func, n, semaphores);
772
773 if (!ctx->Extensions.EXT_semaphore) {
774 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
775 return;
776 }
777
778 if (n < 0) {
779 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
780 return;
781 }
782
783 if (!semaphores)
784 return;
785
786 _mesa_HashLockMutex(&ctx->Shared->SemaphoreObjects);
787 if (_mesa_HashFindFreeKeys(&ctx->Shared->SemaphoreObjects, semaphores, n)) {
788 for (GLsizei i = 0; i < n; i++) {
789 _mesa_HashInsertLocked(&ctx->Shared->SemaphoreObjects, semaphores[i],
790 &DummySemaphoreObject);
791 }
792 }
793
794 _mesa_HashUnlockMutex(&ctx->Shared->SemaphoreObjects);
795 }
796
797 void GLAPIENTRY
_mesa_DeleteSemaphoresEXT(GLsizei n,const GLuint * semaphores)798 _mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
799 {
800 GET_CURRENT_CONTEXT(ctx);
801
802 const char *func = "glDeleteSemaphoresEXT";
803
804 if (MESA_VERBOSE & (VERBOSE_API)) {
805 _mesa_debug(ctx, "%s(%d, %p)\n", func, n, semaphores);
806 }
807
808 if (!ctx->Extensions.EXT_semaphore) {
809 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
810 return;
811 }
812
813 if (n < 0) {
814 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
815 return;
816 }
817
818 if (!semaphores)
819 return;
820
821 _mesa_HashLockMutex(&ctx->Shared->SemaphoreObjects);
822 for (GLint i = 0; i < n; i++) {
823 if (semaphores[i] > 0) {
824 struct gl_semaphore_object *delObj
825 = _mesa_lookup_semaphore_object_locked(ctx, semaphores[i]);
826
827 if (delObj) {
828 _mesa_HashRemoveLocked(&ctx->Shared->SemaphoreObjects,
829 semaphores[i]);
830 _mesa_delete_semaphore_object(ctx, delObj);
831 }
832 }
833 }
834 _mesa_HashUnlockMutex(&ctx->Shared->SemaphoreObjects);
835 }
836
837 GLboolean GLAPIENTRY
_mesa_IsSemaphoreEXT(GLuint semaphore)838 _mesa_IsSemaphoreEXT(GLuint semaphore)
839 {
840 GET_CURRENT_CONTEXT(ctx);
841
842 if (!ctx->Extensions.EXT_semaphore) {
843 _mesa_error(ctx, GL_INVALID_OPERATION, "glIsSemaphoreEXT(unsupported)");
844 return GL_FALSE;
845 }
846
847 struct gl_semaphore_object *obj =
848 _mesa_lookup_semaphore_object(ctx, semaphore);
849
850 return obj ? GL_TRUE : GL_FALSE;
851 }
852
853 /**
854 * Helper that outputs the correct error status for parameter
855 * calls where no pnames are defined
856 */
857 static void
semaphore_parameter_stub(const char * func,GLenum pname)858 semaphore_parameter_stub(const char* func, GLenum pname)
859 {
860 }
861
862 void GLAPIENTRY
_mesa_SemaphoreParameterui64vEXT(GLuint semaphore,GLenum pname,const GLuint64 * params)863 _mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
864 GLenum pname,
865 const GLuint64 *params)
866 {
867 GET_CURRENT_CONTEXT(ctx);
868 const char *func = "glSemaphoreParameterui64vEXT";
869
870 if (!ctx->Extensions.EXT_semaphore) {
871 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
872 return;
873 }
874
875 if (pname != GL_D3D12_FENCE_VALUE_EXT) {
876 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
877 return;
878 }
879
880 struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx,
881 semaphore);
882 if (!semObj)
883 return;
884
885 if (semObj->type != PIPE_FD_TYPE_TIMELINE_SEMAPHORE) {
886 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(Not a D3D12 fence)", func);
887 return;
888 }
889
890 semObj->timeline_value = params[0];
891 ctx->screen->set_fence_timeline_value(ctx->screen, semObj->fence, params[0]);
892 }
893
894 void GLAPIENTRY
_mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,GLenum pname,GLuint64 * params)895 _mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,
896 GLenum pname,
897 GLuint64 *params)
898 {
899 GET_CURRENT_CONTEXT(ctx);
900 const char *func = "glGetSemaphoreParameterui64vEXT";
901
902 if (!ctx->Extensions.EXT_semaphore) {
903 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
904 return;
905 }
906
907 if (pname != GL_D3D12_FENCE_VALUE_EXT) {
908 _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
909 return;
910 }
911
912 struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx,
913 semaphore);
914 if (!semObj)
915 return;
916
917 if (semObj->type != PIPE_FD_TYPE_TIMELINE_SEMAPHORE) {
918 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(Not a D3D12 fence)", func);
919 return;
920 }
921
922 params[0] = semObj->timeline_value;
923 }
924
925 void GLAPIENTRY
_mesa_WaitSemaphoreEXT(GLuint semaphore,GLuint numBufferBarriers,const GLuint * buffers,GLuint numTextureBarriers,const GLuint * textures,const GLenum * srcLayouts)926 _mesa_WaitSemaphoreEXT(GLuint semaphore,
927 GLuint numBufferBarriers,
928 const GLuint *buffers,
929 GLuint numTextureBarriers,
930 const GLuint *textures,
931 const GLenum *srcLayouts)
932 {
933 GET_CURRENT_CONTEXT(ctx);
934 struct gl_semaphore_object *semObj = NULL;
935 struct gl_buffer_object **bufObjs = NULL;
936 struct gl_texture_object **texObjs = NULL;
937
938 const char *func = "glWaitSemaphoreEXT";
939
940 if (!ctx->Extensions.EXT_semaphore) {
941 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
942 return;
943 }
944
945 ASSERT_OUTSIDE_BEGIN_END(ctx);
946
947 semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
948 if (!semObj)
949 return;
950
951 FLUSH_VERTICES(ctx, 0, 0);
952
953 bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
954 if (!bufObjs) {
955 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
956 func, numBufferBarriers);
957 goto end;
958 }
959
960 for (unsigned i = 0; i < numBufferBarriers; i++) {
961 bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
962 }
963
964 texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
965 if (!texObjs) {
966 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
967 func, numTextureBarriers);
968 goto end;
969 }
970
971 for (unsigned i = 0; i < numTextureBarriers; i++) {
972 texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
973 }
974
975 server_wait_semaphore(ctx, semObj,
976 numBufferBarriers, bufObjs,
977 numTextureBarriers, texObjs,
978 srcLayouts);
979
980 end:
981 free(bufObjs);
982 free(texObjs);
983 }
984
985 void GLAPIENTRY
_mesa_SignalSemaphoreEXT(GLuint semaphore,GLuint numBufferBarriers,const GLuint * buffers,GLuint numTextureBarriers,const GLuint * textures,const GLenum * dstLayouts)986 _mesa_SignalSemaphoreEXT(GLuint semaphore,
987 GLuint numBufferBarriers,
988 const GLuint *buffers,
989 GLuint numTextureBarriers,
990 const GLuint *textures,
991 const GLenum *dstLayouts)
992 {
993 GET_CURRENT_CONTEXT(ctx);
994 struct gl_semaphore_object *semObj = NULL;
995 struct gl_buffer_object **bufObjs = NULL;
996 struct gl_texture_object **texObjs = NULL;
997
998 const char *func = "glSignalSemaphoreEXT";
999
1000 if (!ctx->Extensions.EXT_semaphore) {
1001 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
1002 return;
1003 }
1004
1005 ASSERT_OUTSIDE_BEGIN_END(ctx);
1006
1007 semObj = _mesa_lookup_semaphore_object(ctx, semaphore);
1008 if (!semObj)
1009 return;
1010
1011 FLUSH_VERTICES(ctx, 0, 0);
1012
1013 bufObjs = malloc(sizeof(struct gl_buffer_object *) * numBufferBarriers);
1014 if (!bufObjs) {
1015 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numBufferBarriers=%u)",
1016 func, numBufferBarriers);
1017 goto end;
1018 }
1019
1020 for (unsigned i = 0; i < numBufferBarriers; i++) {
1021 bufObjs[i] = _mesa_lookup_bufferobj(ctx, buffers[i]);
1022 }
1023
1024 texObjs = malloc(sizeof(struct gl_texture_object *) * numTextureBarriers);
1025 if (!texObjs) {
1026 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(numTextureBarriers=%u)",
1027 func, numTextureBarriers);
1028 goto end;
1029 }
1030
1031 for (unsigned i = 0; i < numTextureBarriers; i++) {
1032 texObjs[i] = _mesa_lookup_texture(ctx, textures[i]);
1033 }
1034
1035 server_signal_semaphore(ctx, semObj,
1036 numBufferBarriers, bufObjs,
1037 numTextureBarriers, texObjs,
1038 dstLayouts);
1039
1040 end:
1041 free(bufObjs);
1042 free(texObjs);
1043 }
1044
1045 void GLAPIENTRY
_mesa_ImportMemoryFdEXT(GLuint memory,GLuint64 size,GLenum handleType,GLint fd)1046 _mesa_ImportMemoryFdEXT(GLuint memory,
1047 GLuint64 size,
1048 GLenum handleType,
1049 GLint fd)
1050 {
1051 GET_CURRENT_CONTEXT(ctx);
1052
1053 const char *func = "glImportMemoryFdEXT";
1054
1055 if (!ctx->Extensions.EXT_memory_object_fd) {
1056 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
1057 return;
1058 }
1059
1060 if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
1061 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
1062 return;
1063 }
1064
1065 struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
1066 if (!memObj)
1067 return;
1068
1069 import_memoryobj_fd(ctx, memObj, size, fd);
1070 memObj->Immutable = GL_TRUE;
1071 }
1072
1073 void GLAPIENTRY
_mesa_ImportMemoryWin32HandleEXT(GLuint memory,GLuint64 size,GLenum handleType,void * handle)1074 _mesa_ImportMemoryWin32HandleEXT(GLuint memory,
1075 GLuint64 size,
1076 GLenum handleType,
1077 void *handle)
1078 {
1079 GET_CURRENT_CONTEXT(ctx);
1080
1081 const char *func = "glImportMemoryWin32HandleEXT";
1082
1083 if (!ctx->Extensions.EXT_memory_object_win32) {
1084 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
1085 return;
1086 }
1087
1088 if (handleType != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT &&
1089 handleType != GL_HANDLE_TYPE_D3D11_IMAGE_EXT &&
1090 handleType != GL_HANDLE_TYPE_D3D12_RESOURCE_EXT &&
1091 handleType != GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT) {
1092 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
1093 return;
1094 }
1095
1096 struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
1097 if (!memObj)
1098 return;
1099
1100 import_memoryobj_win32(ctx, memObj, size, handle, NULL);
1101 memObj->Immutable = GL_TRUE;
1102 }
1103
1104 void GLAPIENTRY
_mesa_ImportMemoryWin32NameEXT(GLuint memory,GLuint64 size,GLenum handleType,const void * name)1105 _mesa_ImportMemoryWin32NameEXT(GLuint memory,
1106 GLuint64 size,
1107 GLenum handleType,
1108 const void *name)
1109 {
1110 GET_CURRENT_CONTEXT(ctx);
1111
1112 const char *func = "glImportMemoryWin32NameEXT";
1113
1114 if (!ctx->Extensions.EXT_memory_object_win32) {
1115 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
1116 return;
1117 }
1118
1119 if (handleType != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT &&
1120 handleType != GL_HANDLE_TYPE_D3D11_IMAGE_EXT &&
1121 handleType != GL_HANDLE_TYPE_D3D12_RESOURCE_EXT &&
1122 handleType != GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT) {
1123 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
1124 return;
1125 }
1126
1127 struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
1128 if (!memObj)
1129 return;
1130
1131 import_memoryobj_win32(ctx, memObj, size, NULL, name);
1132 memObj->Immutable = GL_TRUE;
1133 }
1134
1135 void GLAPIENTRY
_mesa_ImportSemaphoreFdEXT(GLuint semaphore,GLenum handleType,GLint fd)1136 _mesa_ImportSemaphoreFdEXT(GLuint semaphore,
1137 GLenum handleType,
1138 GLint fd)
1139 {
1140 GET_CURRENT_CONTEXT(ctx);
1141
1142 const char *func = "glImportSemaphoreFdEXT";
1143
1144 if (!ctx->Extensions.EXT_semaphore_fd) {
1145 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
1146 return;
1147 }
1148
1149 if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
1150 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
1151 return;
1152 }
1153
1154 struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx,
1155 semaphore);
1156 if (!semObj)
1157 return;
1158
1159 if (semObj == &DummySemaphoreObject) {
1160 semObj = semaphoreobj_alloc(ctx, semaphore);
1161 if (!semObj) {
1162 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
1163 return;
1164 }
1165 _mesa_HashInsert(&ctx->Shared->SemaphoreObjects, semaphore, semObj);
1166 }
1167
1168 import_semaphoreobj_fd(ctx, semObj, fd);
1169 }
1170
1171 void GLAPIENTRY
_mesa_ImportSemaphoreWin32HandleEXT(GLuint semaphore,GLenum handleType,void * handle)1172 _mesa_ImportSemaphoreWin32HandleEXT(GLuint semaphore,
1173 GLenum handleType,
1174 void *handle)
1175 {
1176 GET_CURRENT_CONTEXT(ctx);
1177
1178 const char *func = "glImportSemaphoreWin32HandleEXT";
1179
1180 if (!ctx->Extensions.EXT_semaphore_win32) {
1181 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
1182 return;
1183 }
1184
1185 if (handleType != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT &&
1186 handleType != GL_HANDLE_TYPE_D3D12_FENCE_EXT) {
1187 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
1188 return;
1189 }
1190
1191 if (handleType == GL_HANDLE_TYPE_D3D12_FENCE_EXT &&
1192 !ctx->screen->get_param(ctx->screen, PIPE_CAP_TIMELINE_SEMAPHORE_IMPORT)) {
1193 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
1194 }
1195
1196 struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx,
1197 semaphore);
1198 if (!semObj)
1199 return;
1200
1201 if (semObj == &DummySemaphoreObject) {
1202 semObj = semaphoreobj_alloc(ctx, semaphore);
1203 if (!semObj) {
1204 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
1205 return;
1206 }
1207 _mesa_HashInsert(&ctx->Shared->SemaphoreObjects, semaphore, semObj);
1208 }
1209
1210 enum pipe_fd_type type = handleType == GL_HANDLE_TYPE_D3D12_FENCE_EXT ?
1211 PIPE_FD_TYPE_TIMELINE_SEMAPHORE : PIPE_FD_TYPE_SYNCOBJ;
1212 import_semaphoreobj_win32(ctx, semObj, handle, NULL, type);
1213 }
1214
1215 void GLAPIENTRY
_mesa_ImportSemaphoreWin32NameEXT(GLuint semaphore,GLenum handleType,const void * name)1216 _mesa_ImportSemaphoreWin32NameEXT(GLuint semaphore,
1217 GLenum handleType,
1218 const void *name)
1219 {
1220 GET_CURRENT_CONTEXT(ctx);
1221
1222 const char *func = "glImportSemaphoreWin32HandleEXT";
1223
1224 if (!ctx->Extensions.EXT_semaphore_win32) {
1225 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
1226 return;
1227 }
1228
1229 if (handleType != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT &&
1230 handleType != GL_HANDLE_TYPE_D3D12_FENCE_EXT) {
1231 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
1232 return;
1233 }
1234
1235 if (handleType == GL_HANDLE_TYPE_D3D12_FENCE_EXT &&
1236 !ctx->screen->get_param(ctx->screen, PIPE_CAP_TIMELINE_SEMAPHORE_IMPORT)) {
1237 _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType);
1238 }
1239
1240 struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx,
1241 semaphore);
1242 if (!semObj)
1243 return;
1244
1245 if (semObj == &DummySemaphoreObject) {
1246 semObj = semaphoreobj_alloc(ctx, semaphore);
1247 if (!semObj) {
1248 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
1249 return;
1250 }
1251 _mesa_HashInsert(&ctx->Shared->SemaphoreObjects, semaphore, semObj);
1252 }
1253
1254 enum pipe_fd_type type = handleType == GL_HANDLE_TYPE_D3D12_FENCE_EXT ?
1255 PIPE_FD_TYPE_TIMELINE_SEMAPHORE : PIPE_FD_TYPE_SYNCOBJ;
1256 import_semaphoreobj_win32(ctx, semObj, NULL, name, type);
1257 }
1258