diff options
Diffstat (limited to 'src/freedreno/vulkan/tu_kgsl.c')
-rw-r--r-- | src/freedreno/vulkan/tu_kgsl.c | 696 |
1 files changed, 0 insertions, 696 deletions
diff --git a/src/freedreno/vulkan/tu_kgsl.c b/src/freedreno/vulkan/tu_kgsl.c deleted file mode 100644 index ce9665ee999..00000000000 --- a/src/freedreno/vulkan/tu_kgsl.c +++ /dev/null @@ -1,696 +0,0 @@ -/* - * Copyright © 2020 Google, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#include "tu_private.h" - -#include <errno.h> -#include <fcntl.h> -#include <stdint.h> -#include <sys/ioctl.h> -#include <sys/mman.h> - -#include "msm_kgsl.h" -#include "vk_util.h" - -struct tu_syncobj { - struct vk_object_base base; - uint32_t timestamp; - bool timestamp_valid; -}; - -static int -safe_ioctl(int fd, unsigned long request, void *arg) -{ - int ret; - - do { - ret = ioctl(fd, request, arg); - } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); - - return ret; -} - -int -tu_drm_submitqueue_new(const struct tu_device *dev, - int priority, - uint32_t *queue_id) -{ - struct kgsl_drawctxt_create req = { - .flags = KGSL_CONTEXT_SAVE_GMEM | - KGSL_CONTEXT_NO_GMEM_ALLOC | - KGSL_CONTEXT_PREAMBLE, - }; - - int ret = safe_ioctl(dev->physical_device->local_fd, IOCTL_KGSL_DRAWCTXT_CREATE, &req); - if (ret) - return ret; - - *queue_id = req.drawctxt_id; - - return 0; -} - -void -tu_drm_submitqueue_close(const struct tu_device *dev, uint32_t queue_id) -{ - struct kgsl_drawctxt_destroy req = { - .drawctxt_id = queue_id, - }; - - safe_ioctl(dev->physical_device->local_fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &req); -} - -VkResult -tu_bo_init_new(struct tu_device *dev, struct tu_bo *bo, uint64_t size, - enum tu_bo_alloc_flags flags) -{ - struct kgsl_gpumem_alloc_id req = { - .size = size, - }; - - if (flags & TU_BO_ALLOC_GPU_READ_ONLY) - req.flags |= KGSL_MEMFLAGS_GPUREADONLY; - - int ret; - - ret = safe_ioctl(dev->physical_device->local_fd, - IOCTL_KGSL_GPUMEM_ALLOC_ID, &req); - if (ret) { - return vk_errorf(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY, - "GPUMEM_ALLOC_ID failed (%s)", strerror(errno)); - } - - *bo = (struct tu_bo) { - .gem_handle = req.id, - .size = req.mmapsize, - .iova = req.gpuaddr, - }; - - return VK_SUCCESS; -} - -VkResult -tu_bo_init_dmabuf(struct tu_device *dev, - struct tu_bo *bo, - uint64_t size, - int fd) -{ - struct kgsl_gpuobj_import_dma_buf import_dmabuf = { - .fd = fd, - }; - struct kgsl_gpuobj_import req = { - .priv = (uintptr_t)&import_dmabuf, - .priv_len = sizeof(import_dmabuf), - .flags = 0, - .type = KGSL_USER_MEM_TYPE_DMABUF, - }; - int ret; - - ret = safe_ioctl(dev->physical_device->local_fd, - IOCTL_KGSL_GPUOBJ_IMPORT, &req); - if (ret) - return vk_errorf(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY, - "Failed to import dma-buf (%s)\n", strerror(errno)); - - struct kgsl_gpuobj_info info_req = { - .id = req.id, - }; - - ret = safe_ioctl(dev->physical_device->local_fd, - IOCTL_KGSL_GPUOBJ_INFO, &info_req); - if (ret) - return vk_errorf(dev->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY, - "Failed to get dma-buf info (%s)\n", strerror(errno)); - - *bo = (struct tu_bo) { - .gem_handle = req.id, - .size = info_req.size, - .iova = info_req.gpuaddr, - }; - - return VK_SUCCESS; -} - -int -tu_bo_export_dmabuf(struct tu_device *dev, struct tu_bo *bo) -{ - tu_stub(); - - return -1; -} - -VkResult -tu_bo_map(struct tu_device *dev, struct tu_bo *bo) -{ - if (bo->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); - if (map == MAP_FAILED) - return vk_error(dev->instance, VK_ERROR_MEMORY_MAP_FAILED); - - bo->map = map; - - return VK_SUCCESS; -} - -void -tu_bo_finish(struct tu_device *dev, struct tu_bo *bo) -{ - assert(bo->gem_handle); - - if (bo->map) - munmap(bo->map, bo->size); - - struct kgsl_gpumem_free_id req = { - .id = bo->gem_handle - }; - - safe_ioctl(dev->physical_device->local_fd, IOCTL_KGSL_GPUMEM_FREE_ID, &req); -} - -static VkResult -get_kgsl_prop(int fd, unsigned int type, void *value, size_t size) -{ - struct kgsl_device_getproperty getprop = { - .type = type, - .value = value, - .sizebytes = size, - }; - - return safe_ioctl(fd, IOCTL_KGSL_DEVICE_GETPROPERTY, &getprop); -} - -VkResult -tu_enumerate_devices(struct tu_instance *instance) -{ - static const char path[] = "/dev/kgsl-3d0"; - int fd; - - struct tu_physical_device *device = &instance->physical_devices[0]; - - if (instance->vk.enabled_extensions.KHR_display) - return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER, - "I can't KHR_display"); - - fd = open(path, O_RDWR | O_CLOEXEC); - if (fd < 0) { - instance->physical_device_count = 0; - return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER, - "failed to open device %s", path); - } - - struct kgsl_devinfo info; - if (get_kgsl_prop(fd, KGSL_PROP_DEVICE_INFO, &info, sizeof(info))) - goto fail; - - uint64_t gmem_iova; - if (get_kgsl_prop(fd, KGSL_PROP_UCHE_GMEM_VADDR, &gmem_iova, sizeof(gmem_iova))) - goto fail; - - /* kgsl version check? */ - - if (instance->debug_flags & TU_DEBUG_STARTUP) - mesa_logi("Found compatible device '%s'.", path); - - device->instance = instance; - device->master_fd = -1; - device->local_fd = fd; - - device->dev_id.gpu_id = - ((info.chip_id >> 24) & 0xff) * 100 + - ((info.chip_id >> 16) & 0xff) * 10 + - ((info.chip_id >> 8) & 0xff); - device->dev_id.chip_id = info.chip_id; - device->gmem_size = info.gmem_sizebytes; - device->gmem_base = gmem_iova; - - device->heap.size = tu_get_system_heap_size(); - device->heap.used = 0u; - device->heap.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT; - - if (tu_physical_device_init(device, instance) != VK_SUCCESS) - goto fail; - - instance->physical_device_count = 1; - - return VK_SUCCESS; - -fail: - close(fd); - return VK_ERROR_INITIALIZATION_FAILED; -} - -static int -timestamp_to_fd(struct tu_queue *queue, uint32_t timestamp) -{ - int fd; - struct kgsl_timestamp_event event = { - .type = KGSL_TIMESTAMP_EVENT_FENCE, - .context_id = queue->msm_queue_id, - .timestamp = timestamp, - .priv = &fd, - .len = sizeof(fd), - }; - - int ret = safe_ioctl(queue->device->fd, IOCTL_KGSL_TIMESTAMP_EVENT, &event); - if (ret) - return -1; - - return fd; -} - -/* return true if timestamp a is greater (more recent) then b - * this relies on timestamps never having a difference > (1<<31) - */ -static inline bool -timestamp_cmp(uint32_t a, uint32_t b) -{ - return (int32_t) (a - b) >= 0; -} - -static uint32_t -max_ts(uint32_t a, uint32_t b) -{ - return timestamp_cmp(a, b) ? a : b; -} - -static uint32_t -min_ts(uint32_t a, uint32_t b) -{ - return timestamp_cmp(a, b) ? b : a; -} - -static struct tu_syncobj -sync_merge(const VkSemaphore *syncobjs, uint32_t count, bool wait_all, bool reset) -{ - struct tu_syncobj ret; - - ret.timestamp_valid = false; - - for (uint32_t i = 0; i < count; ++i) { - TU_FROM_HANDLE(tu_syncobj, sync, syncobjs[i]); - - /* TODO: this means the fence is unsignaled and will never become signaled */ - if (!sync->timestamp_valid) - continue; - - if (!ret.timestamp_valid) - ret.timestamp = sync->timestamp; - else if (wait_all) - ret.timestamp = max_ts(ret.timestamp, sync->timestamp); - else - ret.timestamp = min_ts(ret.timestamp, sync->timestamp); - - ret.timestamp_valid = true; - if (reset) - sync->timestamp_valid = false; - - } - return ret; -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_QueueSubmit(VkQueue _queue, - uint32_t submitCount, - const VkSubmitInfo *pSubmits, - VkFence _fence) -{ - TU_FROM_HANDLE(tu_queue, queue, _queue); - TU_FROM_HANDLE(tu_syncobj, fence, _fence); - VkResult result = VK_SUCCESS; - - uint32_t max_entry_count = 0; - for (uint32_t i = 0; i < submitCount; ++i) { - const VkSubmitInfo *submit = pSubmits + i; - - const VkPerformanceQuerySubmitInfoKHR *perf_info = - vk_find_struct_const(pSubmits[i].pNext, - PERFORMANCE_QUERY_SUBMIT_INFO_KHR); - - uint32_t entry_count = 0; - for (uint32_t j = 0; j < submit->commandBufferCount; ++j) { - TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, submit->pCommandBuffers[j]); - entry_count += cmdbuf->cs.entry_count; - if (perf_info) - entry_count++; - } - - max_entry_count = MAX2(max_entry_count, entry_count); - } - - struct kgsl_command_object *cmds = - vk_alloc(&queue->device->vk.alloc, - sizeof(cmds[0]) * max_entry_count, 8, - VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); - if (cmds == NULL) - return vk_error(queue->device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); - - for (uint32_t i = 0; i < submitCount; ++i) { - const VkSubmitInfo *submit = pSubmits + i; - uint32_t entry_idx = 0; - const VkPerformanceQuerySubmitInfoKHR *perf_info = - vk_find_struct_const(pSubmits[i].pNext, - PERFORMANCE_QUERY_SUBMIT_INFO_KHR); - - - for (uint32_t j = 0; j < submit->commandBufferCount; j++) { - TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, submit->pCommandBuffers[j]); - struct tu_cs *cs = &cmdbuf->cs; - - if (perf_info) { - struct tu_cs_entry *perf_cs_entry = - &cmdbuf->device->perfcntrs_pass_cs_entries[perf_info->counterPassIndex]; - - cmds[entry_idx++] = (struct kgsl_command_object) { - .offset = perf_cs_entry->offset, - .gpuaddr = perf_cs_entry->bo->iova, - .size = perf_cs_entry->size, - .flags = KGSL_CMDLIST_IB, - .id = perf_cs_entry->bo->gem_handle, - }; - } - - for (unsigned k = 0; k < cs->entry_count; k++) { - cmds[entry_idx++] = (struct kgsl_command_object) { - .offset = cs->entries[k].offset, - .gpuaddr = cs->entries[k].bo->iova, - .size = cs->entries[k].size, - .flags = KGSL_CMDLIST_IB, - .id = cs->entries[k].bo->gem_handle, - }; - } - } - - struct tu_syncobj s = sync_merge(submit->pWaitSemaphores, - submit->waitSemaphoreCount, - true, true); - - struct kgsl_cmd_syncpoint_timestamp ts = { - .context_id = queue->msm_queue_id, - .timestamp = s.timestamp, - }; - struct kgsl_command_syncpoint sync = { - .type = KGSL_CMD_SYNCPOINT_TYPE_TIMESTAMP, - .size = sizeof(ts), - .priv = (uintptr_t) &ts, - }; - - struct kgsl_gpu_command req = { - .flags = KGSL_CMDBATCH_SUBMIT_IB_LIST, - .context_id = queue->msm_queue_id, - .cmdlist = (uint64_t) (uintptr_t) cmds, - .numcmds = entry_idx, - .cmdsize = sizeof(struct kgsl_command_object), - .synclist = (uintptr_t) &sync, - .syncsize = sizeof(struct kgsl_command_syncpoint), - .numsyncs = s.timestamp_valid ? 1 : 0, - }; - - int ret = safe_ioctl(queue->device->physical_device->local_fd, - IOCTL_KGSL_GPU_COMMAND, &req); - if (ret) { - result = tu_device_set_lost(queue->device, - "submit failed: %s\n", strerror(errno)); - goto fail; - } - - for (uint32_t i = 0; i < submit->signalSemaphoreCount; i++) { - TU_FROM_HANDLE(tu_syncobj, sem, submit->pSignalSemaphores[i]); - sem->timestamp = req.timestamp; - sem->timestamp_valid = true; - } - - /* no need to merge fences as queue execution is serialized */ - if (i == submitCount - 1) { - int fd = timestamp_to_fd(queue, req.timestamp); - if (fd < 0) { - result = tu_device_set_lost(queue->device, - "Failed to create sync file for timestamp: %s\n", - strerror(errno)); - goto fail; - } - - if (queue->fence >= 0) - close(queue->fence); - queue->fence = fd; - - if (fence) { - fence->timestamp = req.timestamp; - fence->timestamp_valid = true; - } - } - } -fail: - vk_free(&queue->device->vk.alloc, cmds); - - return result; -} - -static VkResult -sync_create(VkDevice _device, - bool signaled, - bool fence, - const VkAllocationCallbacks *pAllocator, - void **p_sync) -{ - TU_FROM_HANDLE(tu_device, device, _device); - - struct tu_syncobj *sync = - vk_object_alloc(&device->vk, pAllocator, sizeof(*sync), - fence ? VK_OBJECT_TYPE_FENCE : VK_OBJECT_TYPE_SEMAPHORE); - if (!sync) - return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY); - - if (signaled) - tu_finishme("CREATE FENCE SIGNALED"); - - sync->timestamp_valid = false; - *p_sync = sync; - - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_ImportSemaphoreFdKHR(VkDevice _device, - const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo) -{ - tu_finishme("ImportSemaphoreFdKHR"); - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_GetSemaphoreFdKHR(VkDevice _device, - const VkSemaphoreGetFdInfoKHR *pGetFdInfo, - int *pFd) -{ - tu_finishme("GetSemaphoreFdKHR"); - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_CreateSemaphore(VkDevice device, - const VkSemaphoreCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, - VkSemaphore *pSemaphore) -{ - return sync_create(device, false, false, pAllocator, (void**) pSemaphore); -} - -VKAPI_ATTR void VKAPI_CALL -tu_DestroySemaphore(VkDevice _device, - VkSemaphore semaphore, - const VkAllocationCallbacks *pAllocator) -{ - TU_FROM_HANDLE(tu_device, device, _device); - TU_FROM_HANDLE(tu_syncobj, sync, semaphore); - - if (!sync) - return; - - vk_object_free(&device->vk, pAllocator, sync); -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_ImportFenceFdKHR(VkDevice _device, - const VkImportFenceFdInfoKHR *pImportFenceFdInfo) -{ - tu_stub(); - - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_GetFenceFdKHR(VkDevice _device, - const VkFenceGetFdInfoKHR *pGetFdInfo, - int *pFd) -{ - tu_stub(); - - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_CreateFence(VkDevice device, - const VkFenceCreateInfo *info, - const VkAllocationCallbacks *pAllocator, - VkFence *pFence) -{ - return sync_create(device, info->flags & VK_FENCE_CREATE_SIGNALED_BIT, true, - pAllocator, (void**) pFence); -} - -VKAPI_ATTR void VKAPI_CALL -tu_DestroyFence(VkDevice _device, VkFence fence, const VkAllocationCallbacks *pAllocator) -{ - TU_FROM_HANDLE(tu_device, device, _device); - TU_FROM_HANDLE(tu_syncobj, sync, fence); - - if (!sync) - return; - - vk_object_free(&device->vk, pAllocator, sync); -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_WaitForFences(VkDevice _device, - uint32_t count, - const VkFence *pFences, - VkBool32 waitAll, - uint64_t timeout) -{ - TU_FROM_HANDLE(tu_device, device, _device); - struct tu_syncobj s = sync_merge((const VkSemaphore*) pFences, count, waitAll, false); - - if (!s.timestamp_valid) - return VK_SUCCESS; - - int ret = ioctl(device->fd, IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID, - &(struct kgsl_device_waittimestamp_ctxtid) { - .context_id = device->queues[0]->msm_queue_id, - .timestamp = s.timestamp, - .timeout = timeout / 1000000, - }); - if (ret) { - assert(errno == ETIME); - return VK_TIMEOUT; - } - - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_ResetFences(VkDevice _device, uint32_t count, const VkFence *pFences) -{ - for (uint32_t i = 0; i < count; i++) { - TU_FROM_HANDLE(tu_syncobj, sync, pFences[i]); - sync->timestamp_valid = false; - } - return VK_SUCCESS; -} - -VKAPI_ATTR VkResult VKAPI_CALL -tu_GetFenceStatus(VkDevice _device, VkFence _fence) -{ - TU_FROM_HANDLE(tu_device, device, _device); - TU_FROM_HANDLE(tu_syncobj, sync, _fence); - - if (!sync->timestamp_valid) - return VK_NOT_READY; - - int ret = ioctl(device->fd, IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID, - &(struct kgsl_device_waittimestamp_ctxtid) { - .context_id = device->queues[0]->msm_queue_id, - .timestamp = sync->timestamp, - .timeout = 0, - }); - if (ret) { - assert(errno == ETIME); - return VK_NOT_READY; - } - - return VK_SUCCESS; -} - -int -tu_signal_fences(struct tu_device *device, struct tu_syncobj *fence1, struct tu_syncobj *fence2) -{ - tu_finishme("tu_signal_fences"); - return 0; -} - -int -tu_syncobj_to_fd(struct tu_device *device, struct tu_syncobj *sync) -{ - tu_finishme("tu_syncobj_to_fd"); - return -1; -} - -VkResult -tu_device_submit_deferred_locked(struct tu_device *dev) -{ - tu_finishme("tu_device_submit_deferred_locked"); - - return VK_SUCCESS; -} - -VkResult -tu_device_wait_u_trace(struct tu_device *dev, struct tu_u_trace_syncobj *syncobj) -{ - tu_finishme("tu_device_wait_u_trace"); - return VK_SUCCESS; -} - -int -tu_drm_get_timestamp(struct tu_physical_device *device, uint64_t *ts) -{ - tu_finishme("tu_drm_get_timestamp"); - return 0; -} - -#ifdef ANDROID -VKAPI_ATTR VkResult VKAPI_CALL -tu_QueueSignalReleaseImageANDROID(VkQueue _queue, - uint32_t waitSemaphoreCount, - const VkSemaphore *pWaitSemaphores, - VkImage image, - int *pNativeFenceFd) -{ - TU_FROM_HANDLE(tu_queue, queue, _queue); - if (!pNativeFenceFd) - return VK_SUCCESS; - - struct tu_syncobj s = sync_merge(pWaitSemaphores, waitSemaphoreCount, true, true); - - if (!s.timestamp_valid) { - *pNativeFenceFd = -1; - return VK_SUCCESS; - } - - *pNativeFenceFd = timestamp_to_fd(queue, s.timestamp); - - return VK_SUCCESS; -} -#endif |