Path: blob/21.2-virgl/src/intel/common/intel_gem.h
4547 views
/*1* Copyright © 2018 Intel Corporation2*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, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#ifndef INTEL_GEM_H24#define INTEL_GEM_H2526#include "drm-uapi/i915_drm.h"2728#include <assert.h>29#include <errno.h>30#include <stdbool.h>31#include <stdint.h>32#include <stdlib.h>33#include <unistd.h>34#include <sys/ioctl.h>3536static inline uint64_t37intel_canonical_address(uint64_t v)38{39/* From the Broadwell PRM Vol. 2a, MI_LOAD_REGISTER_MEM::MemoryAddress:40*41* "This field specifies the address of the memory location where the42* register value specified in the DWord above will read from. The43* address specifies the DWord location of the data. Range =44* GraphicsVirtualAddress[63:2] for a DWord register GraphicsAddress45* [63:48] are ignored by the HW and assumed to be in correct46* canonical form [63:48] == [47]."47*/48const int shift = 63 - 47;49return (int64_t)(v << shift) >> shift;50}5152/**53* This returns a 48-bit address with the high 16 bits zeroed.54*55* It's the opposite of intel_canonicalize_address.56*/57static inline uint64_t58intel_48b_address(uint64_t v)59{60const int shift = 63 - 47;61return (uint64_t)(v << shift) >> shift;62}6364/**65* Call ioctl, restarting if it is interupted66*/67static inline int68intel_ioctl(int fd, unsigned long request, void *arg)69{70int ret;7172do {73ret = ioctl(fd, request, arg);74} while (ret == -1 && (errno == EINTR || errno == EAGAIN));75return ret;76}7778/**79* A wrapper around DRM_IOCTL_I915_QUERY80*81* Unfortunately, the error semantics of this ioctl are rather annoying so82* it's better to have a common helper.83*/84static inline int85intel_i915_query(int fd, uint64_t query_id, void *buffer,86int32_t *buffer_len)87{88struct drm_i915_query_item item = {89.query_id = query_id,90.length = *buffer_len,91.data_ptr = (uintptr_t)buffer,92};9394struct drm_i915_query args = {95.num_items = 1,96.flags = 0,97.items_ptr = (uintptr_t)&item,98};99100int ret = intel_ioctl(fd, DRM_IOCTL_I915_QUERY, &args);101if (ret != 0)102return -errno;103else if (item.length < 0)104return item.length;105106*buffer_len = item.length;107return 0;108}109110/**111* Query for the given data, allocating as needed112*113* The caller is responsible for freeing the returned pointer.114*/115static inline void *116intel_i915_query_alloc(int fd, uint64_t query_id)117{118int32_t length = 0;119int ret = intel_i915_query(fd, query_id, NULL, &length);120if (ret < 0)121return NULL;122123void *data = calloc(1, length);124assert(data != NULL); /* This shouldn't happen in practice */125if (data == NULL)126return NULL;127128ret = intel_i915_query(fd, query_id, data, &length);129assert(ret == 0); /* We should have caught the error above */130if (ret < 0) {131free(data);132return NULL;133}134135return data;136}137138bool intel_gem_supports_syncobj_wait(int fd);139140#endif /* INTEL_GEM_H */141142143