turnip: add functions to import/export prime fd
Add tu_bo_init_dmabuf, tu_bo_export_dmabuf, tu_gem_import_dmabuf, and tu_gem_export_dmabuf.
This commit is contained in:
parent
d5239bc59c
commit
de89436216
|
@ -73,19 +73,15 @@ tu_get_device_uuid(void *uuid)
|
|||
memset(uuid, 0, VK_UUID_SIZE);
|
||||
}
|
||||
|
||||
VkResult
|
||||
tu_bo_init_new(struct tu_device *dev, struct tu_bo *bo, uint64_t size)
|
||||
static VkResult
|
||||
tu_bo_init(struct tu_device *dev,
|
||||
struct tu_bo *bo,
|
||||
uint32_t gem_handle,
|
||||
uint64_t size)
|
||||
{
|
||||
/* TODO: Choose better flags. As of 2018-11-12, freedreno/drm/msm_bo.c
|
||||
* always sets `flags = MSM_BO_WC`, and we copy that behavior here.
|
||||
*/
|
||||
uint32_t gem_handle = tu_gem_new(dev, size, MSM_BO_WC);
|
||||
if (!gem_handle)
|
||||
goto fail_new;
|
||||
|
||||
uint64_t iova = tu_gem_info_iova(dev, gem_handle);
|
||||
if (!iova)
|
||||
goto fail_info;
|
||||
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
||||
|
||||
*bo = (struct tu_bo) {
|
||||
.gem_handle = gem_handle,
|
||||
|
@ -94,11 +90,50 @@ tu_bo_init_new(struct tu_device *dev, struct tu_bo *bo, uint64_t size)
|
|||
};
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
fail_info:
|
||||
tu_gem_close(dev, bo->gem_handle);
|
||||
fail_new:
|
||||
return vk_error(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
VkResult
|
||||
tu_bo_init_new(struct tu_device *dev, struct tu_bo *bo, uint64_t size)
|
||||
{
|
||||
/* TODO: Choose better flags. As of 2018-11-12, freedreno/drm/msm_bo.c
|
||||
* always sets `flags = MSM_BO_WC`, and we copy that behavior here.
|
||||
*/
|
||||
uint32_t gem_handle = tu_gem_new(dev, size, MSM_BO_WC);
|
||||
if (!gem_handle)
|
||||
return vk_error(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
||||
VkResult result = tu_bo_init(dev, bo, gem_handle, size);
|
||||
if (result != VK_SUCCESS) {
|
||||
tu_gem_close(dev, gem_handle);
|
||||
return vk_error(dev->instance, result);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
tu_bo_init_dmabuf(struct tu_device *dev,
|
||||
struct tu_bo *bo,
|
||||
uint64_t size,
|
||||
int fd)
|
||||
{
|
||||
uint32_t gem_handle = tu_gem_import_dmabuf(dev, fd, size);
|
||||
if (!gem_handle)
|
||||
return vk_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
||||
|
||||
VkResult result = tu_bo_init(dev, bo, gem_handle, size);
|
||||
if (result != VK_SUCCESS) {
|
||||
tu_gem_close(dev, gem_handle);
|
||||
return vk_error(dev->instance, result);
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
int
|
||||
tu_bo_export_dmabuf(struct tu_device *dev, struct tu_bo *bo)
|
||||
{
|
||||
return tu_gem_export_dmabuf(dev, bo->gem_handle);
|
||||
}
|
||||
|
||||
VkResult
|
||||
|
@ -109,7 +144,7 @@ tu_bo_map(struct tu_device *dev, struct tu_bo *bo)
|
|||
|
||||
uint64_t offset = tu_gem_info_offset(dev, bo->gem_handle);
|
||||
if (!offset)
|
||||
return vk_error(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
return vk_error(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
||||
/* TODO: Should we use the wrapper os_mmap() like Freedreno does? */
|
||||
void *map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "tu_private.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <xf86drm.h>
|
||||
|
@ -123,6 +124,34 @@ tu_gem_new(const struct tu_device *dev, uint64_t size, uint32_t flags)
|
|||
return req.handle;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
tu_gem_import_dmabuf(const struct tu_device *dev, int prime_fd, uint64_t size)
|
||||
{
|
||||
/* lseek() to get the real size */
|
||||
off_t real_size = lseek(prime_fd, 0, SEEK_END);
|
||||
lseek(prime_fd, 0, SEEK_SET);
|
||||
if (real_size < 0 || (uint64_t) real_size < size)
|
||||
return 0;
|
||||
|
||||
uint32_t gem_handle;
|
||||
int ret = drmPrimeFDToHandle(dev->physical_device->local_fd, prime_fd,
|
||||
&gem_handle);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return gem_handle;
|
||||
}
|
||||
|
||||
int
|
||||
tu_gem_export_dmabuf(const struct tu_device *dev, uint32_t gem_handle)
|
||||
{
|
||||
int prime_fd;
|
||||
int ret = drmPrimeHandleToFD(dev->physical_device->local_fd, gem_handle,
|
||||
DRM_CLOEXEC, &prime_fd);
|
||||
|
||||
return ret == 0 ? prime_fd : -1;
|
||||
}
|
||||
|
||||
void
|
||||
tu_gem_close(const struct tu_device *dev, uint32_t gem_handle)
|
||||
{
|
||||
|
|
|
@ -442,6 +442,13 @@ struct tu_bo
|
|||
|
||||
VkResult
|
||||
tu_bo_init_new(struct tu_device *dev, struct tu_bo *bo, uint64_t size);
|
||||
VkResult
|
||||
tu_bo_init_dmabuf(struct tu_device *dev,
|
||||
struct tu_bo *bo,
|
||||
uint64_t size,
|
||||
int fd);
|
||||
int
|
||||
tu_bo_export_dmabuf(struct tu_device *dev, struct tu_bo *bo);
|
||||
void
|
||||
tu_bo_finish(struct tu_device *dev, struct tu_bo *bo);
|
||||
VkResult
|
||||
|
@ -1315,6 +1322,12 @@ tu_drm_submitqueue_close(const struct tu_device *dev, uint32_t queue_id);
|
|||
|
||||
uint32_t
|
||||
tu_gem_new(const struct tu_device *dev, uint64_t size, uint32_t flags);
|
||||
uint32_t
|
||||
tu_gem_import_dmabuf(const struct tu_device *dev,
|
||||
int prime_fd,
|
||||
uint64_t size);
|
||||
int
|
||||
tu_gem_export_dmabuf(const struct tu_device *dev, uint32_t gem_handle);
|
||||
void
|
||||
tu_gem_close(const struct tu_device *dev, uint32_t gem_handle);
|
||||
uint64_t
|
||||
|
|
Loading…
Reference in New Issue