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