mirror of
https://github.com/termux/termux-packages.git
synced 2024-12-04 18:45:52 +00:00
193 lines
5.4 KiB
Diff
193 lines
5.4 KiB
Diff
diff --git a/src/freedreno/vulkan/tu_device.cc b/src/freedreno/vulkan/tu_device.cc
|
|
index f892fcedcb3..0a5c4dd7a49 100644
|
|
--- a/src/freedreno/vulkan/tu_device.cc
|
|
+++ b/src/freedreno/vulkan/tu_device.cc
|
|
@@ -2624,6 +2624,14 @@ tu_AllocateMemory(VkDevice _device,
|
|
uint64_t client_address = 0;
|
|
BITMASK_ENUM(tu_bo_alloc_flags) alloc_flags = TU_BO_ALLOC_NO_FLAGS;
|
|
|
|
+ const VkExportMemoryAllocateInfo *export_info = vk_find_struct_const(
|
|
+ pAllocateInfo->pNext, EXPORT_MEMORY_ALLOCATE_INFO);
|
|
+ if (export_info && (export_info->handleTypes &
|
|
+ (VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT |
|
|
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT))) {
|
|
+ alloc_flags |= TU_BO_ALLOC_SHAREABLE;
|
|
+ }
|
|
+
|
|
const VkMemoryOpaqueCaptureAddressAllocateInfo *replay_info =
|
|
vk_find_struct_const(pAllocateInfo->pNext,
|
|
MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO);
|
|
diff --git a/src/freedreno/vulkan/tu_knl.h b/src/freedreno/vulkan/tu_knl.h
|
|
index 78cb442dc93..264000c5ea8 100644
|
|
--- a/src/freedreno/vulkan/tu_knl.h
|
|
+++ b/src/freedreno/vulkan/tu_knl.h
|
|
@@ -21,6 +21,7 @@ enum tu_bo_alloc_flags
|
|
TU_BO_ALLOC_ALLOW_DUMP = 1 << 0,
|
|
TU_BO_ALLOC_GPU_READ_ONLY = 1 << 1,
|
|
TU_BO_ALLOC_REPLAYABLE = 1 << 2,
|
|
+ TU_BO_ALLOC_SHAREABLE = 1 << 3,
|
|
};
|
|
|
|
/* Define tu_timeline_sync type based on drm syncobj for a point type
|
|
@@ -53,6 +54,7 @@ struct tu_bo {
|
|
uint32_t bo_list_idx;
|
|
|
|
bool implicit_sync : 1;
|
|
+ int dmabuf_fd;
|
|
};
|
|
|
|
struct tu_knl {
|
|
diff --git a/src/freedreno/vulkan/tu_knl_kgsl.cc b/src/freedreno/vulkan/tu_knl_kgsl.cc
|
|
index 0c2f16c496c..6a484d83a47 100644
|
|
--- a/src/freedreno/vulkan/tu_knl_kgsl.cc
|
|
+++ b/src/freedreno/vulkan/tu_knl_kgsl.cc
|
|
@@ -11,6 +11,7 @@
|
|
#include <stdint.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/mman.h>
|
|
+#include <linux/dma-heap.h>
|
|
|
|
#include "msm_kgsl.h"
|
|
#include "vk_util.h"
|
|
@@ -18,6 +19,7 @@
|
|
#include "util/u_debug.h"
|
|
#include "util/u_vector.h"
|
|
#include "util/libsync.h"
|
|
+#include "util/os_file.h"
|
|
#include "util/timespec.h"
|
|
|
|
#include "tu_cmd_buffer.h"
|
|
@@ -67,6 +69,57 @@ kgsl_submitqueue_close(struct tu_device *dev, uint32_t queue_id)
|
|
safe_ioctl(dev->physical_device->local_fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &req);
|
|
}
|
|
|
|
+static int
|
|
+dmabuf_alloc(uint64_t size)
|
|
+{
|
|
+ int ret;
|
|
+ int dma_heap = open("/dev/dma_heap/system", O_RDONLY);
|
|
+
|
|
+ if (dma_heap < 0) {
|
|
+ int ion_heap = open("/dev/ion", O_RDONLY);
|
|
+
|
|
+ if (ion_heap < 0)
|
|
+ return -1;
|
|
+
|
|
+ struct ion_allocation_data {
|
|
+ __u64 len;
|
|
+ __u32 heap_id_mask;
|
|
+ __u32 flags;
|
|
+ __u32 fd;
|
|
+ __u32 unused;
|
|
+ } alloc_data = {
|
|
+ .len = size,
|
|
+ /* ION_HEAP_SYSTEM | ION_SYSTEM_HEAP_ID */
|
|
+ .heap_id_mask = (1U << 0) | (1U << 25),
|
|
+ .flags = 0, /* uncached */
|
|
+ };
|
|
+
|
|
+ ret = safe_ioctl(ion_heap, _IOWR('I', 0, struct ion_allocation_data),
|
|
+ &alloc_data);
|
|
+
|
|
+ close(ion_heap);
|
|
+
|
|
+ if (ret)
|
|
+ return -1;
|
|
+
|
|
+ return alloc_data.fd;
|
|
+ } else {
|
|
+ struct dma_heap_allocation_data alloc_data = {
|
|
+ .len = size,
|
|
+ .fd_flags = O_RDWR | O_CLOEXEC,
|
|
+ };
|
|
+
|
|
+ ret = safe_ioctl(dma_heap, DMA_HEAP_IOCTL_ALLOC, &alloc_data);
|
|
+
|
|
+ close(dma_heap);
|
|
+
|
|
+ if (ret)
|
|
+ return -1;
|
|
+
|
|
+ return alloc_data.fd;
|
|
+ }
|
|
+}
|
|
+
|
|
static VkResult
|
|
kgsl_bo_init(struct tu_device *dev,
|
|
struct tu_bo **out_bo,
|
|
@@ -78,6 +131,21 @@ kgsl_bo_init(struct tu_device *dev,
|
|
{
|
|
assert(client_iova == 0);
|
|
|
|
+ if (flags & TU_BO_ALLOC_SHAREABLE) {
|
|
+ int fd = dmabuf_alloc(size);
|
|
+
|
|
+ if (fd < 0) {
|
|
+ return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY,
|
|
+ "DMABUF_ALLOC failed (%s)", strerror(errno));
|
|
+ }
|
|
+
|
|
+ VkResult res = tu_bo_init_dmabuf(dev, out_bo, size, fd);
|
|
+
|
|
+ close(fd);
|
|
+
|
|
+ return res;
|
|
+ }
|
|
+
|
|
struct kgsl_gpumem_alloc_id req = {
|
|
.size = size,
|
|
};
|
|
@@ -113,6 +181,7 @@ kgsl_bo_init(struct tu_device *dev,
|
|
.iova = req.gpuaddr,
|
|
.name = tu_debug_bos_add(dev, req.mmapsize, name),
|
|
.refcnt = 1,
|
|
+ .dmabuf_fd = -1,
|
|
};
|
|
|
|
*out_bo = bo;
|
|
@@ -162,6 +231,7 @@ kgsl_bo_init_dmabuf(struct tu_device *dev,
|
|
.iova = info_req.gpuaddr,
|
|
.name = tu_debug_bos_add(dev, info_req.size, "dmabuf"),
|
|
.refcnt = 1,
|
|
+ .dmabuf_fd = os_dupfd_cloexec(fd),
|
|
};
|
|
|
|
*out_bo = bo;
|
|
@@ -172,9 +242,7 @@ kgsl_bo_init_dmabuf(struct tu_device *dev,
|
|
static int
|
|
kgsl_bo_export_dmabuf(struct tu_device *dev, struct tu_bo *bo)
|
|
{
|
|
- tu_stub();
|
|
-
|
|
- return -1;
|
|
+ return os_dupfd_cloexec(bo->dmabuf_fd);
|
|
}
|
|
|
|
static VkResult
|
|
@@ -183,6 +251,15 @@ kgsl_bo_map(struct tu_device *dev, struct tu_bo *bo)
|
|
if (bo->map)
|
|
return VK_SUCCESS;
|
|
|
|
+ if (bo->dmabuf_fd != -1) {
|
|
+ void *map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->dmabuf_fd, 0);
|
|
+
|
|
+ if (map != MAP_FAILED) {
|
|
+ bo->map = map;
|
|
+ return VK_SUCCESS;
|
|
+ }
|
|
+ }
|
|
+
|
|
uint64_t offset = bo->gem_handle << 12;
|
|
void *map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
|
dev->physical_device->local_fd, offset);
|
|
@@ -210,6 +287,9 @@ kgsl_bo_finish(struct tu_device *dev, struct tu_bo *bo)
|
|
if (bo->map)
|
|
munmap(bo->map, bo->size);
|
|
|
|
+ if (bo->dmabuf_fd != -1)
|
|
+ close(bo->dmabuf_fd);
|
|
+
|
|
struct kgsl_gpumem_free_id req = {
|
|
.id = bo->gem_handle
|
|
};
|