mesa: Implement GL_ARB_texture_filter_anisotropic
[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 (!ctx->Extensions.EXT_memory_object) {
94 _mesa_error(ctx, GL_INVALID_OPERATION,
95 "glDeleteMemoryObjectsEXT(unsupported)");
96 return;
97 }
98
99 if (n < 0) {
100 _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteMemoryObjectsEXT(n < 0)");
101 return;
102 }
103
104 if (!memoryObjects)
105 return;
106
107 _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
108 for (GLint i = 0; i < n; i++) {
109 if (memoryObjects[i] > 0) {
110 struct gl_memory_object *delObj
111 = _mesa_lookup_memory_object_locked(ctx, memoryObjects[i]);
112
113 if (delObj) {
114 _mesa_HashRemoveLocked(ctx->Shared->MemoryObjects,
115 memoryObjects[i]);
116 ctx->Driver.DeleteMemoryObject(ctx, delObj);
117 }
118 }
119 }
120 _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
121 }
122
123 GLboolean GLAPIENTRY
124 _mesa_IsMemoryObjectEXT(GLuint memoryObject)
125 {
126 GET_CURRENT_CONTEXT(ctx);
127
128 if (!ctx->Extensions.EXT_memory_object) {
129 _mesa_error(ctx, GL_INVALID_OPERATION,
130 "glIsMemoryObjectEXT(unsupported)");
131 return GL_FALSE;
132 }
133
134 struct gl_memory_object *obj =
135 _mesa_lookup_memory_object(ctx, memoryObject);
136
137 return obj ? GL_TRUE : GL_FALSE;
138 }
139
140 void GLAPIENTRY
141 _mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects)
142 {
143 GET_CURRENT_CONTEXT(ctx);
144
145 const char *func = "glCreateMemoryObjectsEXT";
146
147 if (MESA_VERBOSE & (VERBOSE_API))
148 _mesa_debug(ctx, "%s(%d, %p)", func, n, memoryObjects);
149
150 if (!ctx->Extensions.EXT_memory_object) {
151 _mesa_error(ctx, GL_INVALID_OPERATION,
152 "glCreateMemoryObjectsEXT(unsupported)");
153 return;
154 }
155
156 if (n < 0) {
157 _mesa_error(ctx, GL_INVALID_VALUE, "%s(n < 0)", func);
158 return;
159 }
160
161 if (!memoryObjects)
162 return;
163
164 _mesa_HashLockMutex(ctx->Shared->MemoryObjects);
165 GLuint first = _mesa_HashFindFreeKeyBlock(ctx->Shared->MemoryObjects, n);
166 if (first) {
167 for (GLsizei i = 0; i < n; i++) {
168 struct gl_memory_object *memObj;
169
170 memoryObjects[i] = first + i;
171
172 /* allocate memory object */
173 memObj = ctx->Driver.NewMemoryObject(ctx, memoryObjects[i]);
174 if (!memObj) {
175 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func);
176 _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
177 return;
178 }
179
180 /* insert into hash table */
181 _mesa_HashInsertLocked(ctx->Shared->MemoryObjects,
182 memoryObjects[i],
183 memObj);
184 }
185 }
186
187 _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects);
188 }
189
190 void GLAPIENTRY
191 _mesa_MemoryObjectParameterivEXT(GLuint memoryObject,
192 GLenum pname,
193 const GLint *params)
194 {
195 GET_CURRENT_CONTEXT(ctx);
196 struct gl_memory_object *memObj;
197
198 if (!ctx->Extensions.EXT_memory_object) {
199 _mesa_error(ctx, GL_INVALID_OPERATION,
200 "glMemoryObjectParameterivEXT(unsupported)");
201 return;
202 }
203
204 memObj = _mesa_lookup_memory_object(ctx, memoryObject);
205 if (!memObj)
206 return;
207
208 if (memObj->Immutable) {
209 _mesa_error(ctx, GL_INVALID_OPERATION,
210 "glMemoryObjectParameterivEXT(memoryObject is immutable");
211 return;
212 }
213
214 switch (pname) {
215 case GL_DEDICATED_MEMORY_OBJECT_EXT:
216 memObj->Dedicated = (GLboolean) params[0];
217 break;
218 case GL_PROTECTED_MEMORY_OBJECT_EXT:
219 /* EXT_protected_textures not supported */
220 goto invalid_pname;
221 default:
222 goto invalid_pname;
223 }
224 return;
225
226 invalid_pname:
227 _mesa_error(ctx, GL_INVALID_ENUM,
228 "glMemoryObjectParameterivEXT(pname=0x%x)", pname);
229 }
230
231 void GLAPIENTRY
232 _mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject,
233 GLenum pname,
234 GLint *params)
235 {
236 GET_CURRENT_CONTEXT(ctx);
237 struct gl_memory_object *memObj;
238
239 if (!ctx->Extensions.EXT_memory_object) {
240 _mesa_error(ctx, GL_INVALID_OPERATION,
241 "glGetMemoryObjectParameterivEXT(unsupported)");
242 return;
243 }
244
245 memObj = _mesa_lookup_memory_object(ctx, memoryObject);
246 if (!memObj)
247 return;
248
249 switch (pname) {
250 case GL_DEDICATED_MEMORY_OBJECT_EXT:
251 *params = (GLint) memObj->Dedicated;
252 break;
253 case GL_PROTECTED_MEMORY_OBJECT_EXT:
254 /* EXT_protected_textures not supported */
255 goto invalid_pname;
256 default:
257 goto invalid_pname;
258 }
259 return;
260
261 invalid_pname:
262 _mesa_error(ctx, GL_INVALID_ENUM,
263 "glGetMemoryObjectParameterivEXT(pname=0x%x)", pname);
264 }
265
266 static struct gl_memory_object *
267 lookup_memory_object_err(struct gl_context *ctx, unsigned memory,
268 const char* func)
269 {
270 if (memory == 0) {
271 _mesa_error(ctx, GL_INVALID_VALUE, "%s(memory=0)", func);
272 return NULL;
273 }
274
275 struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
276 if (!memObj)
277 return NULL;
278
279 if (!memObj->Immutable) {
280 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no associated memory)",
281 func);
282 return NULL;
283 }
284
285 return memObj;
286 }
287
288 /**
289 * Helper used by _mesa_TexStorageMem1/2/3DEXT().
290 */
291 static void
292 texstorage_memory(GLuint dims, GLenum target, GLsizei levels,
293 GLenum internalFormat, GLsizei width, GLsizei height,
294 GLsizei depth, GLuint memory, GLuint64 offset,
295 const char *func)
296 {
297 struct gl_texture_object *texObj;
298 struct gl_memory_object *memObj;
299
300 GET_CURRENT_CONTEXT(ctx);
301
302 if (!ctx->Extensions.EXT_memory_object) {
303 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
304 return;
305 }
306
307 texObj = _mesa_get_current_tex_object(ctx, target);
308 if (!texObj)
309 return;
310
311 memObj = lookup_memory_object_err(ctx, memory, func);
312 if (!memObj)
313 return;
314
315 _mesa_texture_storage_memory(ctx, dims, texObj, memObj, target,
316 levels, internalFormat,
317 width, height, depth, offset, false);
318 }
319
320 static void
321 texstorage_memory_ms(GLuint dims, GLenum target, GLsizei samples,
322 GLenum internalFormat, GLsizei width, GLsizei height,
323 GLsizei depth, GLboolean fixedSampleLocations,
324 GLuint memory, GLuint64 offset, const char* func)
325 {
326 struct gl_texture_object *texObj;
327 struct gl_memory_object *memObj;
328
329 GET_CURRENT_CONTEXT(ctx);
330
331 if (!ctx->Extensions.EXT_memory_object) {
332 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
333 return;
334 }
335
336 texObj = _mesa_get_current_tex_object(ctx, target);
337 if (!texObj)
338 return;
339
340 memObj = lookup_memory_object_err(ctx, memory, func);
341 if (!memObj)
342 return;
343
344 _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, target, samples,
345 internalFormat, width, height, depth,
346 fixedSampleLocations, offset, func);
347 }
348
349 /**
350 * Helper used by _mesa_TextureStorageMem1/2/3DEXT().
351 */
352 static void
353 texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels,
354 GLenum internalFormat, GLsizei width, GLsizei height,
355 GLsizei depth, GLuint memory, GLuint64 offset,
356 const char *func)
357 {
358 struct gl_texture_object *texObj;
359 struct gl_memory_object *memObj;
360
361 GET_CURRENT_CONTEXT(ctx);
362
363 if (!ctx->Extensions.EXT_memory_object) {
364 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
365 return;
366 }
367
368 texObj = _mesa_lookup_texture(ctx, texture);
369 if (!texObj)
370 return;
371
372 memObj = lookup_memory_object_err(ctx, memory, func);
373 if (!memObj)
374 return;
375
376 _mesa_texture_storage_memory(ctx, dims, texObj, memObj, texObj->Target,
377 levels, internalFormat,
378 width, height, depth, offset, true);
379 }
380
381 static void
382 texturestorage_memory_ms(GLuint dims, GLuint texture, GLsizei samples,
383 GLenum internalFormat, GLsizei width, GLsizei height,
384 GLsizei depth, GLboolean fixedSampleLocations,
385 GLuint memory, GLuint64 offset, const char* func)
386 {
387 struct gl_texture_object *texObj;
388 struct gl_memory_object *memObj;
389
390 GET_CURRENT_CONTEXT(ctx);
391
392 if (!ctx->Extensions.EXT_memory_object) {
393 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func);
394 return;
395 }
396
397 texObj = _mesa_lookup_texture(ctx, texture);
398 if (!texObj)
399 return;
400
401 memObj = lookup_memory_object_err(ctx, memory, func);
402 if (!memObj)
403 return;
404
405 _mesa_texture_storage_ms_memory(ctx, dims, texObj, memObj, texObj->Target,
406 samples, internalFormat, width, height,
407 depth, fixedSampleLocations, offset, func);
408 }
409
410 void GLAPIENTRY
411 _mesa_TexStorageMem2DEXT(GLenum target,
412 GLsizei levels,
413 GLenum internalFormat,
414 GLsizei width,
415 GLsizei height,
416 GLuint memory,
417 GLuint64 offset)
418 {
419 texstorage_memory(2, target, levels, internalFormat, width, height, 1,
420 memory, offset, "glTexStorageMem2DEXT");
421 }
422
423 void GLAPIENTRY
424 _mesa_TexStorageMem2DMultisampleEXT(GLenum target,
425 GLsizei samples,
426 GLenum internalFormat,
427 GLsizei width,
428 GLsizei height,
429 GLboolean fixedSampleLocations,
430 GLuint memory,
431 GLuint64 offset)
432 {
433 texstorage_memory_ms(2, target, samples, internalFormat, width, height, 1,
434 fixedSampleLocations, memory, offset,
435 "glTexStorageMem2DMultisampleEXT");
436 }
437
438 void GLAPIENTRY
439 _mesa_TexStorageMem3DEXT(GLenum target,
440 GLsizei levels,
441 GLenum internalFormat,
442 GLsizei width,
443 GLsizei height,
444 GLsizei depth,
445 GLuint memory,
446 GLuint64 offset)
447 {
448 texstorage_memory(3, target, levels, internalFormat, width, height, depth,
449 memory, offset, "glTexStorageMem3DEXT");
450 }
451
452 void GLAPIENTRY
453 _mesa_TexStorageMem3DMultisampleEXT(GLenum target,
454 GLsizei samples,
455 GLenum internalFormat,
456 GLsizei width,
457 GLsizei height,
458 GLsizei depth,
459 GLboolean fixedSampleLocations,
460 GLuint memory,
461 GLuint64 offset)
462 {
463 texstorage_memory_ms(3, target, samples, internalFormat, width, height,
464 depth, fixedSampleLocations, memory, offset,
465 "glTexStorageMem3DMultisampleEXT");
466 }
467
468 void GLAPIENTRY
469 _mesa_TextureStorageMem2DEXT(GLuint texture,
470 GLsizei levels,
471 GLenum internalFormat,
472 GLsizei width,
473 GLsizei height,
474 GLuint memory,
475 GLuint64 offset)
476 {
477 texturestorage_memory(2, texture, levels, internalFormat, width, height, 1,
478 memory, offset, "glTexureStorageMem2DEXT");
479 }
480
481 void GLAPIENTRY
482 _mesa_TextureStorageMem2DMultisampleEXT(GLuint texture,
483 GLsizei samples,
484 GLenum internalFormat,
485 GLsizei width,
486 GLsizei height,
487 GLboolean fixedSampleLocations,
488 GLuint memory,
489 GLuint64 offset)
490 {
491 texturestorage_memory_ms(2, texture, samples, internalFormat, width, height,
492 1, fixedSampleLocations, memory, offset,
493 "glTextureStorageMem2DMultisampleEXT");
494 }
495
496 void GLAPIENTRY
497 _mesa_TextureStorageMem3DEXT(GLuint texture,
498 GLsizei levels,
499 GLenum internalFormat,
500 GLsizei width,
501 GLsizei height,
502 GLsizei depth,
503 GLuint memory,
504 GLuint64 offset)
505 {
506 texturestorage_memory(3, texture, levels, internalFormat, width, height,
507 depth, memory, offset, "glTextureStorageMem3DEXT");
508 }
509
510 void GLAPIENTRY
511 _mesa_TextureStorageMem3DMultisampleEXT(GLuint texture,
512 GLsizei samples,
513 GLenum internalFormat,
514 GLsizei width,
515 GLsizei height,
516 GLsizei depth,
517 GLboolean fixedSampleLocations,
518 GLuint memory,
519 GLuint64 offset)
520 {
521 texturestorage_memory_ms(3, texture, samples, internalFormat, width, height,
522 depth, fixedSampleLocations, memory, offset,
523 "glTextureStorageMem3DMultisampleEXT");
524 }
525
526 void GLAPIENTRY
527 _mesa_TexStorageMem1DEXT(GLenum target,
528 GLsizei levels,
529 GLenum internalFormat,
530 GLsizei width,
531 GLuint memory,
532 GLuint64 offset)
533 {
534 texstorage_memory(1, target, levels, internalFormat, width, 1, 1, memory,
535 offset, "glTexStorageMem1DEXT");
536 }
537
538 void GLAPIENTRY
539 _mesa_TextureStorageMem1DEXT(GLuint texture,
540 GLsizei levels,
541 GLenum internalFormat,
542 GLsizei width,
543 GLuint memory,
544 GLuint64 offset)
545 {
546 texturestorage_memory(1, texture, levels, internalFormat, width, 1, 1,
547 memory, offset, "glTextureStorageMem1DEXT");
548 }
549
550 void GLAPIENTRY
551 _mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores)
552 {
553
554 }
555
556 void GLAPIENTRY
557 _mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores)
558 {
559
560 }
561
562 GLboolean GLAPIENTRY
563 _mesa_IsSemaphoreEXT(GLuint semaphore)
564 {
565 return GL_FALSE;
566 }
567
568 void GLAPIENTRY
569 _mesa_SemaphoreParameterui64vEXT(GLuint semaphore,
570 GLenum pname,
571 const GLuint64 *params)
572 {
573
574 }
575
576 void GLAPIENTRY
577 _mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore,
578 GLenum pname,
579 GLuint64 *params)
580 {
581
582 }
583
584 void GLAPIENTRY
585 _mesa_WaitSemaphoreEXT(GLuint semaphore,
586 GLuint numBufferBarriers,
587 const GLuint *buffers,
588 GLuint numTextureBarriers,
589 const GLuint *textures,
590 const GLenum *srcLayouts)
591 {
592
593 }
594
595 void GLAPIENTRY
596 _mesa_SignalSemaphoreEXT(GLuint semaphore,
597 GLuint numBufferBarriers,
598 const GLuint *buffers,
599 GLuint numTextureBarriers,
600 const GLuint *textures,
601 const GLenum *dstLayouts)
602 {
603
604 }
605
606 void GLAPIENTRY
607 _mesa_ImportMemoryFdEXT(GLuint memory,
608 GLuint64 size,
609 GLenum handleType,
610 GLint fd)
611 {
612 GET_CURRENT_CONTEXT(ctx);
613
614 if (!ctx->Extensions.EXT_memory_object_fd) {
615 _mesa_error(ctx, GL_INVALID_OPERATION,
616 "glImportMemoryFdEXT(unsupported)");
617 return;
618 }
619
620 if (handleType != GL_HANDLE_TYPE_OPAQUE_FD_EXT) {
621 _mesa_error(ctx, GL_INVALID_VALUE, "glImportMemoryFdEXT(handleType=%u)",
622 handleType);
623 return;
624 }
625
626 struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory);
627 if (!memObj)
628 return;
629
630 ctx->Driver.ImportMemoryObjectFd(ctx, memObj, size, fd);
631 memObj->Immutable = GL_TRUE;
632 }
633
634 void GLAPIENTRY
635 _mesa_ImportSemaphoreFdEXT(GLuint semaphore,
636 GLenum handleType,
637 GLint fd)
638 {
639
640 }