098a0999208179b047be7d20bddcbd38e6e846af
[mesa.git] / src / mesa / main / externalobjects.c
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 "externalobjects.h"
27 #include "teximage.h"
28 #include "texobj.h"
29 #include "glformats.h"
30 #include "texstorage.h"
31
32 /**
33 * Allocate and initialize a new memory object. But don't put it into the
34 * memory object hash table.
35 *
36 * Called via ctx->Driver.NewMemoryObject, unless overridden by a device
37 * driver.
38 *
39 * \return pointer to new memory object.
40 */
41 static struct gl_memory_object *
42 _mesa_new_memory_object(struct gl_context *ctx, GLuint name)
43 {
44 struct gl_memory_object *obj = MALLOC_STRUCT(gl_memory_object);
45 if (!obj)
46 return NULL;
47
48 _mesa_initialize_memory_object(ctx, obj, name);
49 return obj;
50 }
51
52 /**
53 * Delete a memory object. Called via ctx->Driver.DeleteMemory().
54 * Not removed from hash table here.
55 */
56 void
57 _mesa_delete_memory_object(struct gl_context *ctx,
58 struct gl_memory_object *memObj)
59 {
60 free(memObj);
61 }
62
63 void
64 _mesa_init_memory_object_functions(struct dd_function_table *driver)
65 {
66 driver->NewMemoryObject = _mesa_new_memory_object;
67 driver->DeleteMemoryObject = _mesa_delete_memory_object;
68 }
69
70 /**
71 * Initialize a buffer object to default values.
72 */
73 void
74 _mesa_initialize_memory_object(struct gl_context *ctx,
75 struct gl_memory_object *obj,
76 GLuint name)
77 {
78 memset(obj, 0, sizeof(struct gl_memory_object));
79 obj->Name = name;
80 obj->Dedicated = GL_FALSE;
81 }
82
83 void GLAPIENTRY
84 _mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects)
85 {
86 GET_CURRENT_CONTEXT(ctx);
87
88 if (MESA_VERBOSE & (VERBOSE_API)) {
89 _mesa_debug(ctx, "glDeleteMemoryObjectsEXT(%d, %p)\n", n,
90 memoryObjects);
91 }
92
93 if (n < 0) {
94 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteMemoryObjectsEXT(n < 0)");
95 return;
96 }
97
98 if (!memoryObjects)
99 return;
100
101 _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
102 for (GLint i = 0; i < n; i++) {
103 if (memoryObjects[i] > 0) {
104 struct gl_memory_object *delObj
105 = _mesa_lookup_memory_object_locked(ctx, memoryObjects[i]);
106
107 if (delObj) {
108 _mesa_HashRemoveLocked(ctx->Shared->MemoryObjects,
109 memoryObjects[i]);
110 ctx->Driver.DeleteMemoryObject(ctx, delObj);
111 }
112 }
113 }
114 _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
115 }
116
117 GLboolean GLAPIENTRY
118 _mesa_IsMemoryObjectEXT(GLuint memoryObject)
119 {
120 GET_CURRENT_CONTEXT(ctx);
121 struct gl_memory_object *obj =
122 _mesa_lookup_memory_object(ctx, memoryObject);
123
124 return obj ? GL_TRUE : GL_FALSE;
125 }
126
127 void GLAPIENTRY
128 _mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
129 {
130 GET_CURRENT_CONTEXT(ctx);
131
132 const char *func = "glCreateMemoryObjectsEXT";
133
134 if (MESA_VERBOSE & (VERBOSE_API))
135 _mesa_debug(ctx, "%s(%d, %p)", func, n, memoryObjects);
136
137 if (n < 0) {
138 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
139 return;
140 }
141
142 if (!memoryObjects)
143 return;
144
145 _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
146 GLuint first = _mesa_HashFindFreeKeyBlock(ctx->Shared->MemoryObjects, n);
147 if (first) {
148 for (GLsizei i = 0; i < n; i++) {
149 struct gl_memory_object *memObj;
150
151 memoryObjects[i] = first + i;
152
153 /* allocate memory object */
154 memObj = ctx->Driver.NewMemoryObject(ctx, memoryObjects[i]);
155 if (!memObj) {
156 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
157 _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
158 return;
159 }
160
161 /* insert into hash table */
162 _mesa_HashInsertLocked(ctx->Shared->MemoryObjects,
163 memoryObjects[i],
164 memObj);
165 }
166 }
167
168 _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
169 }
170
171 void GLAPIENTRY
172 _mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
173 GLenum pname,
174 const GLint *params)
175 {
176 GET_CURRENT_CONTEXT(ctx);
177 struct gl_memory_object *memObj;
178
179 memObj = _mesa_lookup_memory_object(ctx, memoryObject);
180 if (!memObj)
181 return;
182
183 if (memObj->Immutable) {
184 _mesa_error(ctx, GL_INVALID_OPERATION,
185 "glMemoryObjectParameterivEXT(memoryObject is immutable");
186 return;
187 }
188
189 switch (pname) {
190 case GL_DEDICATED_MEMORY_OBJECT_EXT:
191 memObj->Dedicated = (GLboolean) params[0];
192 break;
193 case GL_PROTECTED_MEMORY_OBJECT_EXT:
194 /* EXT_protected_textures not supported */
195 goto invalid_pname;
196 default:
197 goto invalid_pname;
198 }
199 return;
200
201 invalid_pname:
202 _mesa_error(ctx, GL_INVALID_ENUM,
203 "glMemoryObjectParameterivEXT(pname=0x%x)", pname);
204 }
205
206 void GLAPIENTRY
207 _mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
208 GLenum pname,
209 GLint *params)
210 {
211 GET_CURRENT_CONTEXT(ctx);
212 struct gl_memory_object *memObj;
213
214 memObj = _mesa_lookup_memory_object(ctx, memoryObject);
215 if (!memObj)
216 return;
217
218 switch (pname) {
219 case GL_DEDICATED_MEMORY_OBJECT_EXT:
220 *params = (GLint) memObj->Dedicated;
221 break;
222 case GL_PROTECTED_MEMORY_OBJECT_EXT:
223 /* EXT_protected_textures not supported */
224 goto invalid_pname;
225 default:
226 goto invalid_pname;
227 }
228 return;
229
230 invalid_pname:
231 _mesa_error(ctx, GL_INVALID_ENUM,
232 "glGetMemoryObjectParameterivEXT(pname=0x%x)", pname);
233 }
234
235 static struct gl_memory_object *
236 lookup_memory_object_err(struct gl_context *ctx, unsigned memory,
237 const char* func)
238 {
239 if (memory == 0) {
240 _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
241 return NULL;
242 }
243
244 struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
245 if (!memObj)
246 return NULL;
247
248 if (!memObj->Immutable) {
249 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
250 func);
251 return NULL;
252 }
253
254 return memObj;
255 }
256
257 /**
258 * Helper used by _mesa_TexStorageMem1/2/3DEXT().
259 */
260 static void
261 texstorage_memory(GLuint dims, GLenum target, GLsizei levels,
262 GLenum internalFormat, GLsizei width, GLsizei height,
263 GLsizei depth, GLuint memory, GLuint64 offset,
264 const char *func)
265 {
266 struct gl_texture_object *texObj;
267 struct gl_memory_object *memObj;
268
269 GET_CURRENT_CONTEXT(ctx);
270
271 texObj = _mesa_get_current_tex_object(ctx, target);
272 if (!texObj)
273 return;
274
275 memObj = lookup_memory_object_err(ctx, memory, func);
276 if (!memObj)
277 return;
278
279 _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
280 levels, internalFormat,
281 width, height, depth, offset, false);
282 }
283
284 static void
285 texstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
286 GLenum internalFormat, GLsizei width, GLsizei height,
287 GLsizei depth, GLboolean fixedSampleLocations,
288 GLuint memory, GLuint64 offset, const char* func)
289 {
290 struct gl_texture_object *texObj;
291 struct gl_memory_object *memObj;
292
293 GET_CURRENT_CONTEXT(ctx);
294
295 texObj = _mesa_get_current_tex_object(ctx, target);
296 if (!texObj)
297 return;
298
299 memObj = lookup_memory_object_err(ctx, memory, func);
300 if (!memObj)
301 return;
302
303 _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, target, samples,
304 internalFormat, width, height, depth,
305 fixedSampleLocations, offset, func);
306 }
307
308 /**
309 * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
310 */
311 static void
312 texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
313 GLenum internalFormat, GLsizei width, GLsizei height,
314 GLsizei depth, GLuint memory, GLuint64 offset,
315 const char *func)
316 {
317 struct gl_texture_object *texObj;
318 struct gl_memory_object *memObj;
319
320 GET_CURRENT_CONTEXT(ctx);
321
322 texObj = _mesa_lookup_texture(ctx, texture);
323 if (!texObj)
324 return;
325
326 memObj = lookup_memory_object_err(ctx, memory, func);
327 if (!memObj)
328 return;
329
330 _mesa_texture_storage_memory(ctx, dims, texObj, memObj, texObj->Target,
331 levels, internalFormat,
332 width, height, depth, offset, true);
333 }
334
335 static void
336 texturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
337 GLenum internalFormat, GLsizei width, GLsizei height,
338 GLsizei depth, GLboolean fixedSampleLocations,
339 GLuint memory, GLuint64 offset, const char* func)
340 {
341 struct gl_texture_object *texObj;
342 struct gl_memory_object *memObj;
343
344 GET_CURRENT_CONTEXT(ctx);
345
346 texObj = _mesa_lookup_texture(ctx, texture);
347 if (!texObj)
348 return;
349
350 memObj = lookup_memory_object_err(ctx, memory, func);
351 if (!memObj)
352 return;
353
354 _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, texObj->Target,
355 samples, internalFormat, width, height,
356 depth, fixedSampleLocations, offset, func);
357 }
358
359 void GLAPIENTRY
360 _mesa_TexStorageMem2DEXT(GLenum target,
361 GLsizei levels,
362 GLenum internalFormat,
363 GLsizei width,
364 GLsizei height,
365 GLuint memory,
366 GLuint64 offset)
367 {
368 texstorage_memory(2, target, levels, internalFormat, width, height, 1,
369 memory, offset, "glTexStorageMem2DEXT");
370 }
371
372 void GLAPIENTRY
373 _mesa_TexStorageMem2DMultisampleEXT(GLenum target,
374 GLsizei samples,
375 GLenum internalFormat,
376 GLsizei width,
377 GLsizei height,
378 GLboolean fixedSampleLocations,
379 GLuint memory,
380 GLuint64 offset)
381 {
382 texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
383 fixedSampleLocations, memory, offset,
384 "glTexStorageMem2DMultisampleEXT");
385 }
386
387 void GLAPIENTRY
388 _mesa_TexStorageMem3DEXT(GLenum target,
389 GLsizei levels,
390 GLenum internalFormat,
391 GLsizei width,
392 GLsizei height,
393 GLsizei depth,
394 GLuint memory,
395 GLuint64 offset)
396 {
397 texstorage_memory(3, target, levels, internalFormat, width, height, depth,
398 memory, offset, "glTexStorageMem3DEXT");
399 }
400
401 void GLAPIENTRY
402 _mesa_TexStorageMem3DMultisampleEXT(GLenum target,
403 GLsizei samples,
404 GLenum internalFormat,
405 GLsizei width,
406 GLsizei height,
407 GLsizei depth,
408 GLboolean fixedSampleLocations,
409 GLuint memory,
410 GLuint64 offset)
411 {
412 texstorage_memory_ms(3, target, samples, internalFormat, width, height,
413 depth, fixedSampleLocations, memory, offset,
414 "glTexStorageMem3DMultisampleEXT");
415 }
416
417 void GLAPIENTRY
418 _mesa_TextureStorageMem2DEXT(GLuint texture,
419 GLsizei levels,
420 GLenum internalFormat,
421 GLsizei width,
422 GLsizei height,
423 GLuint memory,
424 GLuint64 offset)
425 {
426 texturestorage_memory(2, texture, levels, internalFormat, width, height, 1,
427 memory, offset, "glTexureStorageMem2DEXT");
428 }
429
430 void GLAPIENTRY
431 _mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
432 GLsizei samples,
433 GLenum internalFormat,
434 GLsizei width,
435 GLsizei height,
436 GLboolean fixedSampleLocations,
437 GLuint memory,
438 GLuint64 offset)
439 {
440 texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
441 1, fixedSampleLocations, memory, offset,
442 "glTextureStorageMem2DMultisampleEXT");
443 }
444
445 void GLAPIENTRY
446 _mesa_TextureStorageMem3DEXT(GLuint texture,
447 GLsizei levels,
448 GLenum internalFormat,
449 GLsizei width,
450 GLsizei height,
451 GLsizei depth,
452 GLuint memory,
453 GLuint64 offset)
454 {
455 texturestorage_memory(3, texture, levels, internalFormat, width, height,
456 depth, memory, offset, "glTextureStorageMem3DEXT");
457 }
458
459 void GLAPIENTRY
460 _mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
461 GLsizei samples,
462 GLenum internalFormat,
463 GLsizei width,
464 GLsizei height,
465 GLsizei depth,
466 GLboolean fixedSampleLocations,
467 GLuint memory,
468 GLuint64 offset)
469 {
470 texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
471 depth, fixedSampleLocations, memory, offset,
472 "glTextureStorageMem3DMultisampleEXT");
473 }
474
475 void GLAPIENTRY
476 _mesa_TexStorageMem1DEXT(GLenum target,
477 GLsizei levels,
478 GLenum internalFormat,
479 GLsizei width,
480 GLuint memory,
481 GLuint64 offset)
482 {
483 texstorage_memory(1, target, levels, internalFormat, width, 1, 1, memory,
484 offset, "glTexStorageMem1DEXT");
485 }
486
487 void GLAPIENTRY
488 _mesa_TextureStorageMem1DEXT(GLuint texture,
489 GLsizei levels,
490 GLenum internalFormat,
491 GLsizei width,
492 GLuint memory,
493 GLuint64 offset)
494 {
495 texturestorage_memory(1, texture, levels, internalFormat, width, 1, 1,
496 memory, offset, "glTextureStorageMem1DEXT");
497 }
498
499 void GLAPIENTRY
500 _mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
501 {
502
503 }
504
505 void GLAPIENTRY
506 _mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
507 {
508
509 }
510
511 GLboolean GLAPIENTRY
512 _mesa_IsSemaphoreEXT(GLuint semaphore)
513 {
514 return GL_FALSE;
515 }
516
517 void GLAPIENTRY
518 _mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
519 GLenum pname,
520 const GLuint64 *params)
521 {
522
523 }
524
525 void GLAPIENTRY
526 _mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,
527 GLenum pname,
528 GLuint64 *params)
529 {
530
531 }
532
533 void GLAPIENTRY
534 _mesa_WaitSemaphoreEXT(GLuint semaphore,
535 GLuint numBufferBarriers,
536 const GLuint *buffers,
537 GLuint numTextureBarriers,
538 const GLuint *textures,
539 const GLenum *srcLayouts)
540 {
541
542 }
543
544 void GLAPIENTRY
545 _mesa_SignalSemaphoreEXT(GLuint semaphore,
546 GLuint numBufferBarriers,
547 const GLuint *buffers,
548 GLuint numTextureBarriers,
549 const GLuint *textures,
550 const GLenum *dstLayouts)
551 {
552
553 }
554
555 void GLAPIENTRY
556 _mesa_ImportMemoryFdEXT(GLuint memory,
557 GLuint64 size,
558 GLenum handleType,
559 GLint fd)
560 {
561 GET_CURRENT_CONTEXT(ctx);
562
563 if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
564 _mesa_error(ctx, GL_INVALID_VALUE, "glImportMemoryFdEXT(handleType=%u)",
565 handleType);
566 return;
567 }
568
569 struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
570 if (!memObj)
571 return;
572
573 ctx->Driver.ImportMemoryObjectFd(ctx, memObj, size, fd);
574 memObj->Immutable = GL_TRUE;
575 }
576
577 void GLAPIENTRY
578 _mesa_ImportSemaphoreFdEXT(GLuint semaphore,
579 GLenum handleType,
580 GLint fd)
581 {
582
583 }