static void vrend_create_buffer(struct vrend_resource *gr, uint32_t width, uint32_t flags)
{

   GLbitfield buffer_storage_flags = 0;
   if (flags & VIRGL_RESOURCE_FLAG_MAP_PERSISTENT) {
      buffer_storage_flags |= GL_MAP_PERSISTENT_BIT;
      /* Gallium's storage_flags_to_buffer_flags seems to drop some information, but we have to
       * satisfy the following:
       *
       * "If flags contains GL_MAP_PERSISTENT_BIT, it must also contain at least one of
       *  GL_MAP_READ_BIT or GL_MAP_WRITE_BIT."
       */
      buffer_storage_flags |= GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
   }
   if (flags & VIRGL_RESOURCE_FLAG_MAP_COHERENT)
      buffer_storage_flags |= GL_MAP_COHERENT_BIT;

   gr->storage_bits |= VREND_STORAGE_GL_BUFFER;
   glGenBuffersARB(1, &gr->id);
   glBindBufferARB(gr->target, gr->id);

   if (buffer_storage_flags) {
      if (has_feature(feat_arb_buffer_storage) && !vrend_state.use_external_blob) {
         glBufferStorage(gr->target, width, NULL, buffer_storage_flags);
         gr->map_info = vrend_state.inferred_gl_caching_type;
      }
#ifdef ENABLE_MINIGBM_ALLOCATION
      else if (has_feature(feat_memory_object_fd) && has_feature(feat_memory_object)) {
         GLuint memobj = 0;
         int fd = -1;
	 int ret;

         /* Could use VK too. */
         struct gbm_bo *bo = gbm_bo_create(gbm->device, width, 1,
                                           GBM_FORMAT_R8, GBM_BO_USE_LINEAR);
         if (!bo) {
            vrend_printf("Failed to allocate emulated GL buffer backing storage");
            return;
         }

         ret = virgl_gbm_export_fd(gbm->device, gbm_bo_get_handle(bo).u32, &fd);
         if (ret || fd < 0) {
            vrend_printf("Failed to get file descriptor\n");
            return;
         }

         glCreateMemoryObjectsEXT(1, &memobj);
         glImportMemoryFdEXT(memobj, width, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd);
         glBufferStorageMemEXT(gr->target, width, memobj, 0);
         gr->gbm_bo = bo;
         gr->memobj = memobj;
         gr->storage_bits |= VREND_STORAGE_GBM_BUFFER | VREND_STORAGE_GL_MEMOBJ;

         if (!strcmp(gbm_device_get_backend_name(gbm->device), "i915"))
            gr->map_info = VIRGL_RENDERER_MAP_CACHE_CACHED;
         else
            gr->map_info = VIRGL_RENDERER_MAP_CACHE_WC;
      }
#endif
      else {
         vrend_printf("Missing buffer storage and interop extensions\n");
         return;
      }

      gr->storage_bits |= VREND_STORAGE_GL_IMMUTABLE;
      gr->buffer_storage_flags = buffer_storage_flags;
      gr->size = width;
   } else
      glBufferData(gr->target, width, NULL, GL_STREAM_DRAW);

   glBindBufferARB(gr->target, 0);
}
static void vrend_create_buffer(struct vrend_resource *gr, uint32_t width, uint32_t flags)
{

   GLbitfield buffer_storage_flags = 0;
   if (flags & VIRGL_RESOURCE_FLAG_MAP_PERSISTENT) {
      buffer_storage_flags |= GL_MAP_PERSISTENT_BIT;
       
      buffer_storage_flags |= GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
   }
   if (flags & VIRGL_RESOURCE_FLAG_MAP_COHERENT)
      buffer_storage_flags |= GL_MAP_COHERENT_BIT;

   gr->storage_bits |= VREND_STORAGE_GL_BUFFER;
   glGenBuffersARB(1, &gr->id);
   glBindBufferARB(gr->target, gr->id);

   if (buffer_storage_flags) {
      if (has_feature(feat_arb_buffer_storage) && !vrend_state.use_external_blob) {
         glBufferStorage(gr->target, width, NULL, buffer_storage_flags);
         gr->map_info = vrend_state.inferred_gl_caching_type;
      }
#ifdef ENABLE_MINIGBM_ALLOCATION
      else if (has_feature(feat_memory_object_fd) && has_feature(feat_memory_object)) {
         GLuint memobj = 0;
         int fd = -1;
	 int ret;

          
         struct gbm_bo *bo = gbm_bo_create(gbm->device, width, 1,
                                           GBM_FORMAT_R8, GBM_BO_USE_LINEAR);
         if (!bo) {
            vrend_printf("Failed to allocate emulated GL buffer backing storage");
            return;
         }

         ret = virgl_gbm_export_fd(gbm->device, gbm_bo_get_handle(bo).u32, &fd);
         if (ret || fd < 0) {
            vrend_printf("Failed to get file descriptor\n");
            return;
         }

         glCreateMemoryObjectsEXT(1, &memobj);
         glImportMemoryFdEXT(memobj, width, GL_HANDLE_TYPE_OPAQUE_FD_EXT, fd);
         glBufferStorageMemEXT(gr->target, width, memobj, 0);
         gr->gbm_bo = bo;
         gr->memobj = memobj;
         gr->storage_bits |= VREND_STORAGE_GBM_BUFFER | VREND_STORAGE_GL_MEMOBJ;

         if (!strcmp(gbm_device_get_backend_name(gbm->device), "i915"))
            gr->map_info = VIRGL_RENDERER_MAP_CACHE_CACHED;
         else
            gr->map_info = VIRGL_RENDERER_MAP_CACHE_WC;
      }
#endif
      else {
         vrend_printf("Missing buffer storage and interop extensions\n");
         return;
      }

      gr->storage_bits |= VREND_STORAGE_GL_IMMUTABLE;
      gr->buffer_storage_flags = buffer_storage_flags;
      gr->size = width;
   } else
      glBufferData(gr->target, width, NULL, GL_STREAM_DRAW);

   glBindBufferARB(gr->target, 0);
}