diff --git a/src/intel/common/intel_gem.h b/src/intel/common/intel_gem.h index 1b14099d479..109b7be37d2 100644 --- a/src/intel/common/intel_gem.h +++ b/src/intel/common/intel_gem.h @@ -24,9 +24,13 @@ #ifndef INTEL_GEM_H #define INTEL_GEM_H +#include "drm-uapi/i915_drm.h" + +#include #include #include #include +#include #include #include @@ -72,6 +76,66 @@ intel_ioctl(int fd, unsigned long request, void *arg) return ret; } +/** + * A wrapper around DRM_IOCTL_I915_QUERY + * + * Unfortunately, the error semantics of this ioctl are rather annoying so + * it's better to have a common helper. + */ +static inline int +intel_i915_query(int fd, uint64_t query_id, void *buffer, + int32_t *buffer_len) +{ + struct drm_i915_query_item item = { + .query_id = query_id, + .length = *buffer_len, + .data_ptr = (uintptr_t)buffer, + }; + + struct drm_i915_query args = { + .num_items = 1, + .flags = 0, + .items_ptr = (uintptr_t)&item, + }; + + int ret = intel_ioctl(fd, DRM_IOCTL_I915_QUERY, &args); + if (ret != 0) + return -errno; + else if (item.length < 0) + return item.length; + + *buffer_len = item.length; + return 0; +} + +/** + * Query for the given data, allocating as needed + * + * The caller is responsible for freeing the returned pointer. + */ +static inline void * +intel_i915_query_alloc(int fd, uint64_t query_id) +{ + int32_t length = 0; + int ret = intel_i915_query(fd, query_id, NULL, &length); + if (ret < 0) + return NULL; + + void *data = calloc(1, length); + assert(data != NULL); /* This shouldn't happen in practice */ + if (data == NULL) + return NULL; + + ret = intel_i915_query(fd, query_id, data, &length); + assert(ret == 0); /* We should have caught the error above */ + if (ret < 0) { + free(data); + return NULL; + } + + return data; +} + bool intel_gem_supports_syncobj_wait(int fd); #endif /* INTEL_GEM_H */ diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c index 55f8534d0ea..e10db2e04d7 100644 --- a/src/intel/vulkan/anv_gem.c +++ b/src/intel/vulkan/anv_gem.c @@ -770,50 +770,10 @@ anv_gem_syncobj_timeline_query(struct anv_device *device, return intel_ioctl(device->fd, DRM_IOCTL_SYNCOBJ_QUERY, &args); } -int -anv_i915_query(int fd, uint64_t query_id, void *buffer, - int32_t *buffer_len) -{ - struct drm_i915_query_item item = { - .query_id = query_id, - .length = *buffer_len, - .data_ptr = (uintptr_t)buffer, - }; - - struct drm_i915_query args = { - .num_items = 1, - .flags = 0, - .items_ptr = (uintptr_t)&item, - }; - - int ret = intel_ioctl(fd, DRM_IOCTL_I915_QUERY, &args); - if (ret != 0) - return -errno; - else if (item.length < 0) - return item.length; - - *buffer_len = item.length; - return 0; -} - struct drm_i915_query_engine_info * anv_gem_get_engine_info(int fd) { - int32_t length = 0; - int ret = anv_i915_query(fd, DRM_I915_QUERY_ENGINE_INFO, NULL, &length); - if (ret < 0) - return NULL; - - struct drm_i915_query_engine_info *info = calloc(1, length); - ret = anv_i915_query(fd, DRM_I915_QUERY_ENGINE_INFO, info, &length); - assert(ret == 0); - - if (ret < 0) { - free(info); - return NULL; - } - - return info; + return intel_i915_query_alloc(fd, DRM_I915_QUERY_ENGINE_INFO); } int