1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2020 Google, Inc. 3bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 4bf215546Sopenharmony_ci */ 5bf215546Sopenharmony_ci 6bf215546Sopenharmony_ci#include "tu_drm.h" 7bf215546Sopenharmony_ci 8bf215546Sopenharmony_ci#include <errno.h> 9bf215546Sopenharmony_ci#include <fcntl.h> 10bf215546Sopenharmony_ci#include <sys/ioctl.h> 11bf215546Sopenharmony_ci#include <sys/mman.h> 12bf215546Sopenharmony_ci 13bf215546Sopenharmony_ci#include "msm_kgsl.h" 14bf215546Sopenharmony_ci#include "vk_util.h" 15bf215546Sopenharmony_ci 16bf215546Sopenharmony_ci#include "util/debug.h" 17bf215546Sopenharmony_ci 18bf215546Sopenharmony_ci#include "tu_cmd_buffer.h" 19bf215546Sopenharmony_ci#include "tu_cs.h" 20bf215546Sopenharmony_ci#include "tu_device.h" 21bf215546Sopenharmony_ci#include "tu_dynamic_rendering.h" 22bf215546Sopenharmony_ci 23bf215546Sopenharmony_cistruct tu_syncobj { 24bf215546Sopenharmony_ci struct vk_object_base base; 25bf215546Sopenharmony_ci uint32_t timestamp; 26bf215546Sopenharmony_ci bool timestamp_valid; 27bf215546Sopenharmony_ci}; 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_cistatic int 30bf215546Sopenharmony_cisafe_ioctl(int fd, unsigned long request, void *arg) 31bf215546Sopenharmony_ci{ 32bf215546Sopenharmony_ci int ret; 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci do { 35bf215546Sopenharmony_ci ret = ioctl(fd, request, arg); 36bf215546Sopenharmony_ci } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci return ret; 39bf215546Sopenharmony_ci} 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ciint 42bf215546Sopenharmony_citu_drm_submitqueue_new(const struct tu_device *dev, 43bf215546Sopenharmony_ci int priority, 44bf215546Sopenharmony_ci uint32_t *queue_id) 45bf215546Sopenharmony_ci{ 46bf215546Sopenharmony_ci struct kgsl_drawctxt_create req = { 47bf215546Sopenharmony_ci .flags = KGSL_CONTEXT_SAVE_GMEM | 48bf215546Sopenharmony_ci KGSL_CONTEXT_NO_GMEM_ALLOC | 49bf215546Sopenharmony_ci KGSL_CONTEXT_PREAMBLE, 50bf215546Sopenharmony_ci }; 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci int ret = safe_ioctl(dev->physical_device->local_fd, IOCTL_KGSL_DRAWCTXT_CREATE, &req); 53bf215546Sopenharmony_ci if (ret) 54bf215546Sopenharmony_ci return ret; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci *queue_id = req.drawctxt_id; 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci return 0; 59bf215546Sopenharmony_ci} 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_civoid 62bf215546Sopenharmony_citu_drm_submitqueue_close(const struct tu_device *dev, uint32_t queue_id) 63bf215546Sopenharmony_ci{ 64bf215546Sopenharmony_ci struct kgsl_drawctxt_destroy req = { 65bf215546Sopenharmony_ci .drawctxt_id = queue_id, 66bf215546Sopenharmony_ci }; 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci safe_ioctl(dev->physical_device->local_fd, IOCTL_KGSL_DRAWCTXT_DESTROY, &req); 69bf215546Sopenharmony_ci} 70bf215546Sopenharmony_ci 71bf215546Sopenharmony_ciVkResult 72bf215546Sopenharmony_citu_bo_init_new(struct tu_device *dev, struct tu_bo **out_bo, uint64_t size, 73bf215546Sopenharmony_ci enum tu_bo_alloc_flags flags) 74bf215546Sopenharmony_ci{ 75bf215546Sopenharmony_ci struct kgsl_gpumem_alloc_id req = { 76bf215546Sopenharmony_ci .size = size, 77bf215546Sopenharmony_ci }; 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci if (flags & TU_BO_ALLOC_GPU_READ_ONLY) 80bf215546Sopenharmony_ci req.flags |= KGSL_MEMFLAGS_GPUREADONLY; 81bf215546Sopenharmony_ci 82bf215546Sopenharmony_ci int ret; 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci ret = safe_ioctl(dev->physical_device->local_fd, 85bf215546Sopenharmony_ci IOCTL_KGSL_GPUMEM_ALLOC_ID, &req); 86bf215546Sopenharmony_ci if (ret) { 87bf215546Sopenharmony_ci return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY, 88bf215546Sopenharmony_ci "GPUMEM_ALLOC_ID failed (%s)", strerror(errno)); 89bf215546Sopenharmony_ci } 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci struct tu_bo* bo = tu_device_lookup_bo(dev, req.id); 92bf215546Sopenharmony_ci assert(bo && bo->gem_handle == 0); 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci *bo = (struct tu_bo) { 95bf215546Sopenharmony_ci .gem_handle = req.id, 96bf215546Sopenharmony_ci .size = req.mmapsize, 97bf215546Sopenharmony_ci .iova = req.gpuaddr, 98bf215546Sopenharmony_ci .refcnt = 1, 99bf215546Sopenharmony_ci }; 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci *out_bo = bo; 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci return VK_SUCCESS; 104bf215546Sopenharmony_ci} 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ciVkResult 107bf215546Sopenharmony_citu_bo_init_dmabuf(struct tu_device *dev, 108bf215546Sopenharmony_ci struct tu_bo **out_bo, 109bf215546Sopenharmony_ci uint64_t size, 110bf215546Sopenharmony_ci int fd) 111bf215546Sopenharmony_ci{ 112bf215546Sopenharmony_ci struct kgsl_gpuobj_import_dma_buf import_dmabuf = { 113bf215546Sopenharmony_ci .fd = fd, 114bf215546Sopenharmony_ci }; 115bf215546Sopenharmony_ci struct kgsl_gpuobj_import req = { 116bf215546Sopenharmony_ci .priv = (uintptr_t)&import_dmabuf, 117bf215546Sopenharmony_ci .priv_len = sizeof(import_dmabuf), 118bf215546Sopenharmony_ci .flags = 0, 119bf215546Sopenharmony_ci .type = KGSL_USER_MEM_TYPE_DMABUF, 120bf215546Sopenharmony_ci }; 121bf215546Sopenharmony_ci int ret; 122bf215546Sopenharmony_ci 123bf215546Sopenharmony_ci ret = safe_ioctl(dev->physical_device->local_fd, 124bf215546Sopenharmony_ci IOCTL_KGSL_GPUOBJ_IMPORT, &req); 125bf215546Sopenharmony_ci if (ret) 126bf215546Sopenharmony_ci return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY, 127bf215546Sopenharmony_ci "Failed to import dma-buf (%s)\n", strerror(errno)); 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci struct kgsl_gpuobj_info info_req = { 130bf215546Sopenharmony_ci .id = req.id, 131bf215546Sopenharmony_ci }; 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci ret = safe_ioctl(dev->physical_device->local_fd, 134bf215546Sopenharmony_ci IOCTL_KGSL_GPUOBJ_INFO, &info_req); 135bf215546Sopenharmony_ci if (ret) 136bf215546Sopenharmony_ci return vk_errorf(dev, VK_ERROR_OUT_OF_DEVICE_MEMORY, 137bf215546Sopenharmony_ci "Failed to get dma-buf info (%s)\n", strerror(errno)); 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci struct tu_bo* bo = tu_device_lookup_bo(dev, req.id); 140bf215546Sopenharmony_ci assert(bo && bo->gem_handle == 0); 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci *bo = (struct tu_bo) { 143bf215546Sopenharmony_ci .gem_handle = req.id, 144bf215546Sopenharmony_ci .size = info_req.size, 145bf215546Sopenharmony_ci .iova = info_req.gpuaddr, 146bf215546Sopenharmony_ci .refcnt = 1, 147bf215546Sopenharmony_ci }; 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci *out_bo = bo; 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci return VK_SUCCESS; 152bf215546Sopenharmony_ci} 153bf215546Sopenharmony_ci 154bf215546Sopenharmony_ciint 155bf215546Sopenharmony_citu_bo_export_dmabuf(struct tu_device *dev, struct tu_bo *bo) 156bf215546Sopenharmony_ci{ 157bf215546Sopenharmony_ci tu_stub(); 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_ci return -1; 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ciVkResult 163bf215546Sopenharmony_citu_bo_map(struct tu_device *dev, struct tu_bo *bo) 164bf215546Sopenharmony_ci{ 165bf215546Sopenharmony_ci if (bo->map) 166bf215546Sopenharmony_ci return VK_SUCCESS; 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci uint64_t offset = bo->gem_handle << 12; 169bf215546Sopenharmony_ci void *map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, 170bf215546Sopenharmony_ci dev->physical_device->local_fd, offset); 171bf215546Sopenharmony_ci if (map == MAP_FAILED) 172bf215546Sopenharmony_ci return vk_error(dev, VK_ERROR_MEMORY_MAP_FAILED); 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci bo->map = map; 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci return VK_SUCCESS; 177bf215546Sopenharmony_ci} 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_civoid 180bf215546Sopenharmony_citu_bo_finish(struct tu_device *dev, struct tu_bo *bo) 181bf215546Sopenharmony_ci{ 182bf215546Sopenharmony_ci assert(bo->gem_handle); 183bf215546Sopenharmony_ci 184bf215546Sopenharmony_ci if (!p_atomic_dec_zero(&bo->refcnt)) 185bf215546Sopenharmony_ci return; 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci if (bo->map) 188bf215546Sopenharmony_ci munmap(bo->map, bo->size); 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci struct kgsl_gpumem_free_id req = { 191bf215546Sopenharmony_ci .id = bo->gem_handle 192bf215546Sopenharmony_ci }; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci /* Tell sparse array that entry is free */ 195bf215546Sopenharmony_ci memset(bo, 0, sizeof(*bo)); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci safe_ioctl(dev->physical_device->local_fd, IOCTL_KGSL_GPUMEM_FREE_ID, &req); 198bf215546Sopenharmony_ci} 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_cistatic VkResult 201bf215546Sopenharmony_ciget_kgsl_prop(int fd, unsigned int type, void *value, size_t size) 202bf215546Sopenharmony_ci{ 203bf215546Sopenharmony_ci struct kgsl_device_getproperty getprop = { 204bf215546Sopenharmony_ci .type = type, 205bf215546Sopenharmony_ci .value = value, 206bf215546Sopenharmony_ci .sizebytes = size, 207bf215546Sopenharmony_ci }; 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci return safe_ioctl(fd, IOCTL_KGSL_DEVICE_GETPROPERTY, &getprop); 210bf215546Sopenharmony_ci} 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ciVkResult 213bf215546Sopenharmony_citu_enumerate_devices(struct tu_instance *instance) 214bf215546Sopenharmony_ci{ 215bf215546Sopenharmony_ci static const char path[] = "/dev/kgsl-3d0"; 216bf215546Sopenharmony_ci int fd; 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci struct tu_physical_device *device = &instance->physical_devices[0]; 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_ci if (instance->vk.enabled_extensions.KHR_display) 221bf215546Sopenharmony_ci return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER, 222bf215546Sopenharmony_ci "I can't KHR_display"); 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci fd = open(path, O_RDWR | O_CLOEXEC); 225bf215546Sopenharmony_ci if (fd < 0) { 226bf215546Sopenharmony_ci instance->physical_device_count = 0; 227bf215546Sopenharmony_ci return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER, 228bf215546Sopenharmony_ci "failed to open device %s", path); 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci struct kgsl_devinfo info; 232bf215546Sopenharmony_ci if (get_kgsl_prop(fd, KGSL_PROP_DEVICE_INFO, &info, sizeof(info))) 233bf215546Sopenharmony_ci goto fail; 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci uint64_t gmem_iova; 236bf215546Sopenharmony_ci if (get_kgsl_prop(fd, KGSL_PROP_UCHE_GMEM_VADDR, &gmem_iova, sizeof(gmem_iova))) 237bf215546Sopenharmony_ci goto fail; 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci /* kgsl version check? */ 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci if (instance->debug_flags & TU_DEBUG_STARTUP) 242bf215546Sopenharmony_ci mesa_logi("Found compatible device '%s'.", path); 243bf215546Sopenharmony_ci 244bf215546Sopenharmony_ci device->instance = instance; 245bf215546Sopenharmony_ci device->master_fd = -1; 246bf215546Sopenharmony_ci device->local_fd = fd; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci device->dev_id.gpu_id = 249bf215546Sopenharmony_ci ((info.chip_id >> 24) & 0xff) * 100 + 250bf215546Sopenharmony_ci ((info.chip_id >> 16) & 0xff) * 10 + 251bf215546Sopenharmony_ci ((info.chip_id >> 8) & 0xff); 252bf215546Sopenharmony_ci device->dev_id.chip_id = info.chip_id; 253bf215546Sopenharmony_ci device->gmem_size = env_var_as_unsigned("TU_GMEM", info.gmem_sizebytes); 254bf215546Sopenharmony_ci device->gmem_base = gmem_iova; 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci device->heap.size = tu_get_system_heap_size(); 257bf215546Sopenharmony_ci device->heap.used = 0u; 258bf215546Sopenharmony_ci device->heap.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT; 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci if (tu_physical_device_init(device, instance) != VK_SUCCESS) 261bf215546Sopenharmony_ci goto fail; 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci instance->physical_device_count = 1; 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci return VK_SUCCESS; 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_cifail: 268bf215546Sopenharmony_ci close(fd); 269bf215546Sopenharmony_ci return VK_ERROR_INITIALIZATION_FAILED; 270bf215546Sopenharmony_ci} 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_cistatic int 273bf215546Sopenharmony_citimestamp_to_fd(struct tu_queue *queue, uint32_t timestamp) 274bf215546Sopenharmony_ci{ 275bf215546Sopenharmony_ci int fd; 276bf215546Sopenharmony_ci struct kgsl_timestamp_event event = { 277bf215546Sopenharmony_ci .type = KGSL_TIMESTAMP_EVENT_FENCE, 278bf215546Sopenharmony_ci .context_id = queue->msm_queue_id, 279bf215546Sopenharmony_ci .timestamp = timestamp, 280bf215546Sopenharmony_ci .priv = &fd, 281bf215546Sopenharmony_ci .len = sizeof(fd), 282bf215546Sopenharmony_ci }; 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci int ret = safe_ioctl(queue->device->fd, IOCTL_KGSL_TIMESTAMP_EVENT, &event); 285bf215546Sopenharmony_ci if (ret) 286bf215546Sopenharmony_ci return -1; 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci return fd; 289bf215546Sopenharmony_ci} 290bf215546Sopenharmony_ci 291bf215546Sopenharmony_ci/* return true if timestamp a is greater (more recent) then b 292bf215546Sopenharmony_ci * this relies on timestamps never having a difference > (1<<31) 293bf215546Sopenharmony_ci */ 294bf215546Sopenharmony_cistatic inline bool 295bf215546Sopenharmony_citimestamp_cmp(uint32_t a, uint32_t b) 296bf215546Sopenharmony_ci{ 297bf215546Sopenharmony_ci return (int32_t) (a - b) >= 0; 298bf215546Sopenharmony_ci} 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_cistatic uint32_t 301bf215546Sopenharmony_cimax_ts(uint32_t a, uint32_t b) 302bf215546Sopenharmony_ci{ 303bf215546Sopenharmony_ci return timestamp_cmp(a, b) ? a : b; 304bf215546Sopenharmony_ci} 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_cistatic uint32_t 307bf215546Sopenharmony_cimin_ts(uint32_t a, uint32_t b) 308bf215546Sopenharmony_ci{ 309bf215546Sopenharmony_ci return timestamp_cmp(a, b) ? b : a; 310bf215546Sopenharmony_ci} 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_cistatic struct tu_syncobj 313bf215546Sopenharmony_cisync_merge(const VkSemaphore *syncobjs, uint32_t count, bool wait_all, bool reset) 314bf215546Sopenharmony_ci{ 315bf215546Sopenharmony_ci struct tu_syncobj ret; 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci ret.timestamp_valid = false; 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci for (uint32_t i = 0; i < count; ++i) { 320bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_syncobj, sync, syncobjs[i]); 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci /* TODO: this means the fence is unsignaled and will never become signaled */ 323bf215546Sopenharmony_ci if (!sync->timestamp_valid) 324bf215546Sopenharmony_ci continue; 325bf215546Sopenharmony_ci 326bf215546Sopenharmony_ci if (!ret.timestamp_valid) 327bf215546Sopenharmony_ci ret.timestamp = sync->timestamp; 328bf215546Sopenharmony_ci else if (wait_all) 329bf215546Sopenharmony_ci ret.timestamp = max_ts(ret.timestamp, sync->timestamp); 330bf215546Sopenharmony_ci else 331bf215546Sopenharmony_ci ret.timestamp = min_ts(ret.timestamp, sync->timestamp); 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci ret.timestamp_valid = true; 334bf215546Sopenharmony_ci if (reset) 335bf215546Sopenharmony_ci sync->timestamp_valid = false; 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci return ret; 339bf215546Sopenharmony_ci} 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 342bf215546Sopenharmony_citu_QueueSubmit2(VkQueue _queue, 343bf215546Sopenharmony_ci uint32_t submitCount, 344bf215546Sopenharmony_ci const VkSubmitInfo2 *pSubmits, 345bf215546Sopenharmony_ci VkFence _fence) 346bf215546Sopenharmony_ci{ 347bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_queue, queue, _queue); 348bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_syncobj, fence, _fence); 349bf215546Sopenharmony_ci VkResult result = VK_SUCCESS; 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci if (unlikely(queue->device->physical_device->instance->debug_flags & 352bf215546Sopenharmony_ci TU_DEBUG_LOG_SKIP_GMEM_OPS)) { 353bf215546Sopenharmony_ci tu_dbg_log_gmem_load_store_skips(queue->device); 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci struct tu_cmd_buffer **submit_cmd_buffers[submitCount]; 357bf215546Sopenharmony_ci uint32_t submit_cmd_buffer_count[submitCount]; 358bf215546Sopenharmony_ci 359bf215546Sopenharmony_ci uint32_t max_entry_count = 0; 360bf215546Sopenharmony_ci for (uint32_t i = 0; i < submitCount; ++i) { 361bf215546Sopenharmony_ci const VkSubmitInfo2 *submit = pSubmits + i; 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci const VkPerformanceQuerySubmitInfoKHR *perf_info = 364bf215546Sopenharmony_ci vk_find_struct_const(pSubmits[i].pNext, 365bf215546Sopenharmony_ci PERFORMANCE_QUERY_SUBMIT_INFO_KHR); 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci struct tu_cmd_buffer *old_cmd_buffers[submit->commandBufferInfoCount]; 368bf215546Sopenharmony_ci uint32_t cmdbuf_count = submit->commandBufferInfoCount; 369bf215546Sopenharmony_ci for (uint32_t j = 0; j < cmdbuf_count; ++j) { 370bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_cmd_buffer, cmdbuf, submit->pCommandBufferInfos[j].commandBuffer); 371bf215546Sopenharmony_ci old_cmd_buffers[j] = cmdbuf; 372bf215546Sopenharmony_ci } 373bf215546Sopenharmony_ci 374bf215546Sopenharmony_ci struct tu_cmd_buffer **cmd_buffers = old_cmd_buffers; 375bf215546Sopenharmony_ci tu_insert_dynamic_cmdbufs(queue->device, &cmd_buffers, &cmdbuf_count); 376bf215546Sopenharmony_ci if (cmd_buffers == old_cmd_buffers) { 377bf215546Sopenharmony_ci cmd_buffers = 378bf215546Sopenharmony_ci vk_alloc(&queue->device->vk.alloc, 379bf215546Sopenharmony_ci sizeof(*cmd_buffers) * cmdbuf_count, 8, 380bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 381bf215546Sopenharmony_ci memcpy(cmd_buffers, old_cmd_buffers, 382bf215546Sopenharmony_ci sizeof(*cmd_buffers) * cmdbuf_count); 383bf215546Sopenharmony_ci } 384bf215546Sopenharmony_ci submit_cmd_buffers[i] = cmd_buffers; 385bf215546Sopenharmony_ci submit_cmd_buffer_count[i] = cmdbuf_count; 386bf215546Sopenharmony_ci 387bf215546Sopenharmony_ci uint32_t entry_count = 0; 388bf215546Sopenharmony_ci for (uint32_t j = 0; j < cmdbuf_count; ++j) { 389bf215546Sopenharmony_ci entry_count += cmd_buffers[i]->cs.entry_count; 390bf215546Sopenharmony_ci if (perf_info) 391bf215546Sopenharmony_ci entry_count++; 392bf215546Sopenharmony_ci } 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci if (tu_autotune_submit_requires_fence(cmd_buffers, cmdbuf_count)) 395bf215546Sopenharmony_ci entry_count++; 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci max_entry_count = MAX2(max_entry_count, entry_count); 398bf215546Sopenharmony_ci } 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci struct kgsl_command_object *cmds = 401bf215546Sopenharmony_ci vk_alloc(&queue->device->vk.alloc, 402bf215546Sopenharmony_ci sizeof(cmds[0]) * max_entry_count, 8, 403bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 404bf215546Sopenharmony_ci if (cmds == NULL) 405bf215546Sopenharmony_ci return vk_error(queue, VK_ERROR_OUT_OF_HOST_MEMORY); 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci for (uint32_t i = 0; i < submitCount; ++i) { 408bf215546Sopenharmony_ci const VkSubmitInfo2 *submit = pSubmits + i; 409bf215546Sopenharmony_ci uint32_t entry_idx = 0; 410bf215546Sopenharmony_ci const VkPerformanceQuerySubmitInfoKHR *perf_info = 411bf215546Sopenharmony_ci vk_find_struct_const(pSubmits[i].pNext, 412bf215546Sopenharmony_ci PERFORMANCE_QUERY_SUBMIT_INFO_KHR); 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci struct tu_cmd_buffer **cmd_buffers = submit_cmd_buffers[i]; 416bf215546Sopenharmony_ci uint32_t cmdbuf_count = submit_cmd_buffer_count[i]; 417bf215546Sopenharmony_ci for (uint32_t j = 0; j < cmdbuf_count; j++) { 418bf215546Sopenharmony_ci struct tu_cmd_buffer *cmdbuf = cmd_buffers[j]; 419bf215546Sopenharmony_ci struct tu_cs *cs = &cmdbuf->cs; 420bf215546Sopenharmony_ci 421bf215546Sopenharmony_ci if (perf_info) { 422bf215546Sopenharmony_ci struct tu_cs_entry *perf_cs_entry = 423bf215546Sopenharmony_ci &cmdbuf->device->perfcntrs_pass_cs_entries[perf_info->counterPassIndex]; 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci cmds[entry_idx++] = (struct kgsl_command_object) { 426bf215546Sopenharmony_ci .offset = perf_cs_entry->offset, 427bf215546Sopenharmony_ci .gpuaddr = perf_cs_entry->bo->iova, 428bf215546Sopenharmony_ci .size = perf_cs_entry->size, 429bf215546Sopenharmony_ci .flags = KGSL_CMDLIST_IB, 430bf215546Sopenharmony_ci .id = perf_cs_entry->bo->gem_handle, 431bf215546Sopenharmony_ci }; 432bf215546Sopenharmony_ci } 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci for (unsigned k = 0; k < cs->entry_count; k++) { 435bf215546Sopenharmony_ci cmds[entry_idx++] = (struct kgsl_command_object) { 436bf215546Sopenharmony_ci .offset = cs->entries[k].offset, 437bf215546Sopenharmony_ci .gpuaddr = cs->entries[k].bo->iova, 438bf215546Sopenharmony_ci .size = cs->entries[k].size, 439bf215546Sopenharmony_ci .flags = KGSL_CMDLIST_IB, 440bf215546Sopenharmony_ci .id = cs->entries[k].bo->gem_handle, 441bf215546Sopenharmony_ci }; 442bf215546Sopenharmony_ci } 443bf215546Sopenharmony_ci } 444bf215546Sopenharmony_ci 445bf215546Sopenharmony_ci if (tu_autotune_submit_requires_fence(cmd_buffers, cmdbuf_count)) { 446bf215546Sopenharmony_ci struct tu_cs *autotune_cs = 447bf215546Sopenharmony_ci tu_autotune_on_submit(queue->device, 448bf215546Sopenharmony_ci &queue->device->autotune, 449bf215546Sopenharmony_ci cmd_buffers, 450bf215546Sopenharmony_ci cmdbuf_count); 451bf215546Sopenharmony_ci cmds[entry_idx++] = (struct kgsl_command_object) { 452bf215546Sopenharmony_ci .offset = autotune_cs->entries[0].offset, 453bf215546Sopenharmony_ci .gpuaddr = autotune_cs->entries[0].bo->iova, 454bf215546Sopenharmony_ci .size = autotune_cs->entries[0].size, 455bf215546Sopenharmony_ci .flags = KGSL_CMDLIST_IB, 456bf215546Sopenharmony_ci .id = autotune_cs->entries[0].bo->gem_handle, 457bf215546Sopenharmony_ci }; 458bf215546Sopenharmony_ci } 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci VkSemaphore wait_semaphores[submit->waitSemaphoreInfoCount]; 461bf215546Sopenharmony_ci for (uint32_t j = 0; j < submit->waitSemaphoreInfoCount; j++) { 462bf215546Sopenharmony_ci wait_semaphores[j] = submit->pWaitSemaphoreInfos[j].semaphore; 463bf215546Sopenharmony_ci } 464bf215546Sopenharmony_ci 465bf215546Sopenharmony_ci struct tu_syncobj s = sync_merge(wait_semaphores, 466bf215546Sopenharmony_ci submit->waitSemaphoreInfoCount, 467bf215546Sopenharmony_ci true, true); 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci struct kgsl_cmd_syncpoint_timestamp ts = { 470bf215546Sopenharmony_ci .context_id = queue->msm_queue_id, 471bf215546Sopenharmony_ci .timestamp = s.timestamp, 472bf215546Sopenharmony_ci }; 473bf215546Sopenharmony_ci struct kgsl_command_syncpoint sync = { 474bf215546Sopenharmony_ci .type = KGSL_CMD_SYNCPOINT_TYPE_TIMESTAMP, 475bf215546Sopenharmony_ci .size = sizeof(ts), 476bf215546Sopenharmony_ci .priv = (uintptr_t) &ts, 477bf215546Sopenharmony_ci }; 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci struct kgsl_gpu_command req = { 480bf215546Sopenharmony_ci .flags = KGSL_CMDBATCH_SUBMIT_IB_LIST, 481bf215546Sopenharmony_ci .context_id = queue->msm_queue_id, 482bf215546Sopenharmony_ci .cmdlist = (uint64_t) (uintptr_t) cmds, 483bf215546Sopenharmony_ci .numcmds = entry_idx, 484bf215546Sopenharmony_ci .cmdsize = sizeof(struct kgsl_command_object), 485bf215546Sopenharmony_ci .synclist = (uintptr_t) &sync, 486bf215546Sopenharmony_ci .syncsize = sizeof(struct kgsl_command_syncpoint), 487bf215546Sopenharmony_ci .numsyncs = s.timestamp_valid ? 1 : 0, 488bf215546Sopenharmony_ci }; 489bf215546Sopenharmony_ci 490bf215546Sopenharmony_ci int ret = safe_ioctl(queue->device->physical_device->local_fd, 491bf215546Sopenharmony_ci IOCTL_KGSL_GPU_COMMAND, &req); 492bf215546Sopenharmony_ci if (ret) { 493bf215546Sopenharmony_ci result = vk_device_set_lost(&queue->device->vk, 494bf215546Sopenharmony_ci "submit failed: %s\n", strerror(errno)); 495bf215546Sopenharmony_ci goto fail; 496bf215546Sopenharmony_ci } 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci for (uint32_t i = 0; i < submit->signalSemaphoreInfoCount; i++) { 499bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_syncobj, sem, submit->pSignalSemaphoreInfos[i].semaphore); 500bf215546Sopenharmony_ci sem->timestamp = req.timestamp; 501bf215546Sopenharmony_ci sem->timestamp_valid = true; 502bf215546Sopenharmony_ci } 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci /* no need to merge fences as queue execution is serialized */ 505bf215546Sopenharmony_ci if (i == submitCount - 1) { 506bf215546Sopenharmony_ci int fd = timestamp_to_fd(queue, req.timestamp); 507bf215546Sopenharmony_ci if (fd < 0) { 508bf215546Sopenharmony_ci result = vk_device_set_lost(&queue->device->vk, 509bf215546Sopenharmony_ci "Failed to create sync file for timestamp: %s\n", 510bf215546Sopenharmony_ci strerror(errno)); 511bf215546Sopenharmony_ci goto fail; 512bf215546Sopenharmony_ci } 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci if (queue->fence >= 0) 515bf215546Sopenharmony_ci close(queue->fence); 516bf215546Sopenharmony_ci queue->fence = fd; 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ci if (fence) { 519bf215546Sopenharmony_ci fence->timestamp = req.timestamp; 520bf215546Sopenharmony_ci fence->timestamp_valid = true; 521bf215546Sopenharmony_ci } 522bf215546Sopenharmony_ci } 523bf215546Sopenharmony_ci } 524bf215546Sopenharmony_cifail: 525bf215546Sopenharmony_ci vk_free(&queue->device->vk.alloc, cmds); 526bf215546Sopenharmony_ci 527bf215546Sopenharmony_ci return result; 528bf215546Sopenharmony_ci} 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_cistatic VkResult 531bf215546Sopenharmony_cisync_create(VkDevice _device, 532bf215546Sopenharmony_ci bool signaled, 533bf215546Sopenharmony_ci bool fence, 534bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 535bf215546Sopenharmony_ci void **p_sync) 536bf215546Sopenharmony_ci{ 537bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_device, device, _device); 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci struct tu_syncobj *sync = 540bf215546Sopenharmony_ci vk_object_alloc(&device->vk, pAllocator, sizeof(*sync), 541bf215546Sopenharmony_ci fence ? VK_OBJECT_TYPE_FENCE : VK_OBJECT_TYPE_SEMAPHORE); 542bf215546Sopenharmony_ci if (!sync) 543bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 544bf215546Sopenharmony_ci 545bf215546Sopenharmony_ci if (signaled) 546bf215546Sopenharmony_ci tu_finishme("CREATE FENCE SIGNALED"); 547bf215546Sopenharmony_ci 548bf215546Sopenharmony_ci sync->timestamp_valid = false; 549bf215546Sopenharmony_ci *p_sync = sync; 550bf215546Sopenharmony_ci 551bf215546Sopenharmony_ci return VK_SUCCESS; 552bf215546Sopenharmony_ci} 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 555bf215546Sopenharmony_citu_ImportSemaphoreFdKHR(VkDevice _device, 556bf215546Sopenharmony_ci const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo) 557bf215546Sopenharmony_ci{ 558bf215546Sopenharmony_ci tu_finishme("ImportSemaphoreFdKHR"); 559bf215546Sopenharmony_ci return VK_SUCCESS; 560bf215546Sopenharmony_ci} 561bf215546Sopenharmony_ci 562bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 563bf215546Sopenharmony_citu_GetSemaphoreFdKHR(VkDevice _device, 564bf215546Sopenharmony_ci const VkSemaphoreGetFdInfoKHR *pGetFdInfo, 565bf215546Sopenharmony_ci int *pFd) 566bf215546Sopenharmony_ci{ 567bf215546Sopenharmony_ci tu_finishme("GetSemaphoreFdKHR"); 568bf215546Sopenharmony_ci return VK_SUCCESS; 569bf215546Sopenharmony_ci} 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 572bf215546Sopenharmony_citu_CreateSemaphore(VkDevice device, 573bf215546Sopenharmony_ci const VkSemaphoreCreateInfo *pCreateInfo, 574bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 575bf215546Sopenharmony_ci VkSemaphore *pSemaphore) 576bf215546Sopenharmony_ci{ 577bf215546Sopenharmony_ci return sync_create(device, false, false, pAllocator, (void**) pSemaphore); 578bf215546Sopenharmony_ci} 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 581bf215546Sopenharmony_citu_DestroySemaphore(VkDevice _device, 582bf215546Sopenharmony_ci VkSemaphore semaphore, 583bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 584bf215546Sopenharmony_ci{ 585bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_device, device, _device); 586bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_syncobj, sync, semaphore); 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci if (!sync) 589bf215546Sopenharmony_ci return; 590bf215546Sopenharmony_ci 591bf215546Sopenharmony_ci vk_object_free(&device->vk, pAllocator, sync); 592bf215546Sopenharmony_ci} 593bf215546Sopenharmony_ci 594bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 595bf215546Sopenharmony_citu_ImportFenceFdKHR(VkDevice _device, 596bf215546Sopenharmony_ci const VkImportFenceFdInfoKHR *pImportFenceFdInfo) 597bf215546Sopenharmony_ci{ 598bf215546Sopenharmony_ci tu_stub(); 599bf215546Sopenharmony_ci 600bf215546Sopenharmony_ci return VK_SUCCESS; 601bf215546Sopenharmony_ci} 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 604bf215546Sopenharmony_citu_GetFenceFdKHR(VkDevice _device, 605bf215546Sopenharmony_ci const VkFenceGetFdInfoKHR *pGetFdInfo, 606bf215546Sopenharmony_ci int *pFd) 607bf215546Sopenharmony_ci{ 608bf215546Sopenharmony_ci tu_stub(); 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci return VK_SUCCESS; 611bf215546Sopenharmony_ci} 612bf215546Sopenharmony_ci 613bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 614bf215546Sopenharmony_citu_CreateFence(VkDevice device, 615bf215546Sopenharmony_ci const VkFenceCreateInfo *info, 616bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, 617bf215546Sopenharmony_ci VkFence *pFence) 618bf215546Sopenharmony_ci{ 619bf215546Sopenharmony_ci return sync_create(device, info->flags & VK_FENCE_CREATE_SIGNALED_BIT, true, 620bf215546Sopenharmony_ci pAllocator, (void**) pFence); 621bf215546Sopenharmony_ci} 622bf215546Sopenharmony_ci 623bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 624bf215546Sopenharmony_citu_DestroyFence(VkDevice _device, VkFence fence, const VkAllocationCallbacks *pAllocator) 625bf215546Sopenharmony_ci{ 626bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_device, device, _device); 627bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_syncobj, sync, fence); 628bf215546Sopenharmony_ci 629bf215546Sopenharmony_ci if (!sync) 630bf215546Sopenharmony_ci return; 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_ci vk_object_free(&device->vk, pAllocator, sync); 633bf215546Sopenharmony_ci} 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 636bf215546Sopenharmony_citu_WaitForFences(VkDevice _device, 637bf215546Sopenharmony_ci uint32_t count, 638bf215546Sopenharmony_ci const VkFence *pFences, 639bf215546Sopenharmony_ci VkBool32 waitAll, 640bf215546Sopenharmony_ci uint64_t timeout) 641bf215546Sopenharmony_ci{ 642bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_device, device, _device); 643bf215546Sopenharmony_ci struct tu_syncobj s = sync_merge((const VkSemaphore*) pFences, count, waitAll, false); 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci if (!s.timestamp_valid) 646bf215546Sopenharmony_ci return VK_SUCCESS; 647bf215546Sopenharmony_ci 648bf215546Sopenharmony_ci int ret = ioctl(device->fd, IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID, 649bf215546Sopenharmony_ci &(struct kgsl_device_waittimestamp_ctxtid) { 650bf215546Sopenharmony_ci .context_id = device->queues[0]->msm_queue_id, 651bf215546Sopenharmony_ci .timestamp = s.timestamp, 652bf215546Sopenharmony_ci .timeout = timeout / 1000000, 653bf215546Sopenharmony_ci }); 654bf215546Sopenharmony_ci if (ret) { 655bf215546Sopenharmony_ci assert(errno == ETIME); 656bf215546Sopenharmony_ci return VK_TIMEOUT; 657bf215546Sopenharmony_ci } 658bf215546Sopenharmony_ci 659bf215546Sopenharmony_ci return VK_SUCCESS; 660bf215546Sopenharmony_ci} 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 663bf215546Sopenharmony_citu_ResetFences(VkDevice _device, uint32_t count, const VkFence *pFences) 664bf215546Sopenharmony_ci{ 665bf215546Sopenharmony_ci for (uint32_t i = 0; i < count; i++) { 666bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_syncobj, sync, pFences[i]); 667bf215546Sopenharmony_ci sync->timestamp_valid = false; 668bf215546Sopenharmony_ci } 669bf215546Sopenharmony_ci return VK_SUCCESS; 670bf215546Sopenharmony_ci} 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 673bf215546Sopenharmony_citu_GetFenceStatus(VkDevice _device, VkFence _fence) 674bf215546Sopenharmony_ci{ 675bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_device, device, _device); 676bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_syncobj, sync, _fence); 677bf215546Sopenharmony_ci 678bf215546Sopenharmony_ci if (!sync->timestamp_valid) 679bf215546Sopenharmony_ci return VK_NOT_READY; 680bf215546Sopenharmony_ci 681bf215546Sopenharmony_ci int ret = ioctl(device->fd, IOCTL_KGSL_DEVICE_WAITTIMESTAMP_CTXTID, 682bf215546Sopenharmony_ci &(struct kgsl_device_waittimestamp_ctxtid) { 683bf215546Sopenharmony_ci .context_id = device->queues[0]->msm_queue_id, 684bf215546Sopenharmony_ci .timestamp = sync->timestamp, 685bf215546Sopenharmony_ci .timeout = 0, 686bf215546Sopenharmony_ci }); 687bf215546Sopenharmony_ci if (ret) { 688bf215546Sopenharmony_ci assert(errno == ETIME); 689bf215546Sopenharmony_ci return VK_NOT_READY; 690bf215546Sopenharmony_ci } 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_ci return VK_SUCCESS; 693bf215546Sopenharmony_ci} 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ciint 696bf215546Sopenharmony_citu_syncobj_to_fd(struct tu_device *device, struct vk_sync *sync) 697bf215546Sopenharmony_ci{ 698bf215546Sopenharmony_ci tu_finishme("tu_syncobj_to_fd"); 699bf215546Sopenharmony_ci return -1; 700bf215546Sopenharmony_ci} 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ciVkResult 703bf215546Sopenharmony_citu_device_wait_u_trace(struct tu_device *dev, struct tu_u_trace_syncobj *syncobj) 704bf215546Sopenharmony_ci{ 705bf215546Sopenharmony_ci tu_finishme("tu_device_wait_u_trace"); 706bf215546Sopenharmony_ci return VK_SUCCESS; 707bf215546Sopenharmony_ci} 708bf215546Sopenharmony_ci 709bf215546Sopenharmony_ciint 710bf215546Sopenharmony_citu_device_get_gpu_timestamp(struct tu_device *dev, uint64_t *ts) 711bf215546Sopenharmony_ci{ 712bf215546Sopenharmony_ci tu_finishme("tu_device_get_gpu_timestamp"); 713bf215546Sopenharmony_ci return 0; 714bf215546Sopenharmony_ci} 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ciint 717bf215546Sopenharmony_citu_device_get_suspend_count(struct tu_device *dev, uint64_t *suspend_count) 718bf215546Sopenharmony_ci{ 719bf215546Sopenharmony_ci /* kgsl doesn't have a way to get it */ 720bf215546Sopenharmony_ci *suspend_count = 0; 721bf215546Sopenharmony_ci return 0; 722bf215546Sopenharmony_ci} 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ciVkResult 725bf215546Sopenharmony_citu_device_check_status(struct vk_device *vk_device) 726bf215546Sopenharmony_ci{ 727bf215546Sopenharmony_ci struct tu_device *device = container_of(vk_device, struct tu_device, vk); 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_ci for (unsigned i = 0; i < TU_MAX_QUEUE_FAMILIES; i++) { 730bf215546Sopenharmony_ci for (unsigned q = 0; q < device->queue_count[i]; q++) { 731bf215546Sopenharmony_ci /* KGSL's KGSL_PROP_GPU_RESET_STAT takes the u32 msm_queue_id and returns a 732bf215546Sopenharmony_ci * KGSL_CTX_STAT_* for the worst reset that happened since the last time it 733bf215546Sopenharmony_ci * was queried on that queue. 734bf215546Sopenharmony_ci */ 735bf215546Sopenharmony_ci uint32_t value = device->queues[i][q].msm_queue_id; 736bf215546Sopenharmony_ci VkResult status = get_kgsl_prop(device->fd, KGSL_PROP_GPU_RESET_STAT, 737bf215546Sopenharmony_ci &value, sizeof(value)); 738bf215546Sopenharmony_ci if (status != VK_SUCCESS) 739bf215546Sopenharmony_ci return vk_device_set_lost(&device->vk, "Failed to get GPU reset status"); 740bf215546Sopenharmony_ci 741bf215546Sopenharmony_ci if (value != KGSL_CTX_STAT_NO_ERROR && 742bf215546Sopenharmony_ci value != KGSL_CTX_STAT_INNOCENT_CONTEXT_RESET_EXT) { 743bf215546Sopenharmony_ci return vk_device_set_lost(&device->vk, "GPU faulted or hung"); 744bf215546Sopenharmony_ci } 745bf215546Sopenharmony_ci } 746bf215546Sopenharmony_ci } 747bf215546Sopenharmony_ci 748bf215546Sopenharmony_ci return VK_SUCCESS; 749bf215546Sopenharmony_ci} 750bf215546Sopenharmony_ci 751bf215546Sopenharmony_ci#ifdef ANDROID 752bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 753bf215546Sopenharmony_citu_QueueSignalReleaseImageANDROID(VkQueue _queue, 754bf215546Sopenharmony_ci uint32_t waitSemaphoreCount, 755bf215546Sopenharmony_ci const VkSemaphore *pWaitSemaphores, 756bf215546Sopenharmony_ci VkImage image, 757bf215546Sopenharmony_ci int *pNativeFenceFd) 758bf215546Sopenharmony_ci{ 759bf215546Sopenharmony_ci TU_FROM_HANDLE(tu_queue, queue, _queue); 760bf215546Sopenharmony_ci if (!pNativeFenceFd) 761bf215546Sopenharmony_ci return VK_SUCCESS; 762bf215546Sopenharmony_ci 763bf215546Sopenharmony_ci struct tu_syncobj s = sync_merge(pWaitSemaphores, waitSemaphoreCount, true, true); 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci if (!s.timestamp_valid) { 766bf215546Sopenharmony_ci *pNativeFenceFd = -1; 767bf215546Sopenharmony_ci return VK_SUCCESS; 768bf215546Sopenharmony_ci } 769bf215546Sopenharmony_ci 770bf215546Sopenharmony_ci *pNativeFenceFd = timestamp_to_fd(queue, s.timestamp); 771bf215546Sopenharmony_ci 772bf215546Sopenharmony_ci return VK_SUCCESS; 773bf215546Sopenharmony_ci} 774bf215546Sopenharmony_ci#endif 775