Path: blob/21.2-virgl/src/freedreno/drm/freedreno_device.c
4564 views
/*1* Copyright (C) 2012-2018 Rob Clark <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,19* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE20* SOFTWARE.21*22* Authors:23* Rob Clark <[email protected]>24*/2526#include <unistd.h>27#include <sys/stat.h>28#include <sys/types.h>2930#include "util/os_file.h"3132#include "freedreno_drmif.h"33#include "freedreno_priv.h"3435struct fd_device *msm_device_new(int fd, drmVersionPtr version);3637struct fd_device *38fd_device_new(int fd)39{40struct fd_device *dev;41drmVersionPtr version;4243/* figure out if we are kgsl or msm drm driver: */44version = drmGetVersion(fd);45if (!version) {46ERROR_MSG("cannot get version: %s", strerror(errno));47return NULL;48}4950if (!strcmp(version->name, "msm")) {51DEBUG_MSG("msm DRM device");52if (version->version_major != 1) {53ERROR_MSG("unsupported version: %u.%u.%u", version->version_major,54version->version_minor, version->version_patchlevel);55dev = NULL;56goto out;57}5859dev = msm_device_new(fd, version);60dev->version = version->version_minor;61#if HAVE_FREEDRENO_KGSL62} else if (!strcmp(version->name, "kgsl")) {63DEBUG_MSG("kgsl DRM device");64dev = kgsl_device_new(fd);65#endif66} else {67ERROR_MSG("unknown device: %s", version->name);68dev = NULL;69}7071out:72drmFreeVersion(version);7374if (!dev)75return NULL;7677p_atomic_set(&dev->refcnt, 1);78dev->fd = fd;79dev->handle_table =80_mesa_hash_table_create(NULL, _mesa_hash_u32, _mesa_key_u32_equal);81dev->name_table =82_mesa_hash_table_create(NULL, _mesa_hash_u32, _mesa_key_u32_equal);83fd_bo_cache_init(&dev->bo_cache, false);84fd_bo_cache_init(&dev->ring_cache, true);8586list_inithead(&dev->deferred_submits);87simple_mtx_init(&dev->submit_lock, mtx_plain);8889return dev;90}9192/* like fd_device_new() but creates it's own private dup() of the fd93* which is close()d when the device is finalized.94*/95struct fd_device *96fd_device_new_dup(int fd)97{98int dup_fd = os_dupfd_cloexec(fd);99struct fd_device *dev = fd_device_new(dup_fd);100if (dev)101dev->closefd = 1;102else103close(dup_fd);104return dev;105}106107struct fd_device *108fd_device_ref(struct fd_device *dev)109{110p_atomic_inc(&dev->refcnt);111return dev;112}113114void115fd_device_purge(struct fd_device *dev)116{117simple_mtx_lock(&table_lock);118fd_bo_cache_cleanup(&dev->bo_cache, 0);119fd_bo_cache_cleanup(&dev->ring_cache, 0);120simple_mtx_unlock(&table_lock);121}122123static void124fd_device_del_impl(struct fd_device *dev)125{126int close_fd = dev->closefd ? dev->fd : -1;127128simple_mtx_assert_locked(&table_lock);129130assert(list_is_empty(&dev->deferred_submits));131132fd_bo_cache_cleanup(&dev->bo_cache, 0);133fd_bo_cache_cleanup(&dev->ring_cache, 0);134_mesa_hash_table_destroy(dev->handle_table, NULL);135_mesa_hash_table_destroy(dev->name_table, NULL);136dev->funcs->destroy(dev);137if (close_fd >= 0)138close(close_fd);139}140141void142fd_device_del_locked(struct fd_device *dev)143{144if (!p_atomic_dec_zero(&dev->refcnt))145return;146fd_device_del_impl(dev);147}148149void150fd_device_del(struct fd_device *dev)151{152if (!p_atomic_dec_zero(&dev->refcnt))153return;154simple_mtx_lock(&table_lock);155fd_device_del_impl(dev);156simple_mtx_unlock(&table_lock);157}158159int160fd_device_fd(struct fd_device *dev)161{162return dev->fd;163}164165enum fd_version166fd_device_version(struct fd_device *dev)167{168return dev->version;169}170171bool172fd_dbg(void)173{174static int dbg;175176if (!dbg)177dbg = getenv("LIBGL_DEBUG") ? 1 : -1;178179return dbg == 1;180}181182bool183fd_has_syncobj(struct fd_device *dev)184{185uint64_t value;186if (drmGetCap(dev->fd, DRM_CAP_SYNCOBJ, &value))187return false;188return value && dev->version >= FD_VERSION_FENCE_FD;189}190191192