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