17ec681f3Smrg/* 27ec681f3Smrg * Copyright 2019 Google LLC 37ec681f3Smrg * SPDX-License-Identifier: MIT 47ec681f3Smrg * 57ec681f3Smrg * based in part on anv and radv which are: 67ec681f3Smrg * Copyright © 2015 Intel Corporation 77ec681f3Smrg * Copyright © 2016 Red Hat. 87ec681f3Smrg * Copyright © 2016 Bas Nieuwenhuizen 97ec681f3Smrg */ 107ec681f3Smrg 117ec681f3Smrg#include "vn_buffer.h" 127ec681f3Smrg 137ec681f3Smrg#include "venus-protocol/vn_protocol_driver_buffer.h" 147ec681f3Smrg#include "venus-protocol/vn_protocol_driver_buffer_view.h" 157ec681f3Smrg 167ec681f3Smrg#include "vn_android.h" 177ec681f3Smrg#include "vn_device.h" 187ec681f3Smrg#include "vn_device_memory.h" 197ec681f3Smrg 207ec681f3Smrg/* buffer commands */ 217ec681f3Smrg 227ec681f3SmrgVkResult 237ec681f3Smrgvn_buffer_create(struct vn_device *dev, 247ec681f3Smrg const VkBufferCreateInfo *create_info, 257ec681f3Smrg const VkAllocationCallbacks *alloc, 267ec681f3Smrg struct vn_buffer **out_buf) 277ec681f3Smrg{ 287ec681f3Smrg VkDevice device = vn_device_to_handle(dev); 297ec681f3Smrg struct vn_buffer *buf = NULL; 307ec681f3Smrg VkBuffer buffer = VK_NULL_HANDLE; 317ec681f3Smrg VkResult result; 327ec681f3Smrg 337ec681f3Smrg buf = vk_zalloc(alloc, sizeof(*buf), VN_DEFAULT_ALIGN, 347ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 357ec681f3Smrg if (!buf) 367ec681f3Smrg return VK_ERROR_OUT_OF_HOST_MEMORY; 377ec681f3Smrg 387ec681f3Smrg vn_object_base_init(&buf->base, VK_OBJECT_TYPE_BUFFER, &dev->base); 397ec681f3Smrg 407ec681f3Smrg buffer = vn_buffer_to_handle(buf); 417ec681f3Smrg /* TODO async */ 427ec681f3Smrg result = vn_call_vkCreateBuffer(dev->instance, device, create_info, NULL, 437ec681f3Smrg &buffer); 447ec681f3Smrg if (result != VK_SUCCESS) { 457ec681f3Smrg vn_object_base_fini(&buf->base); 467ec681f3Smrg vk_free(alloc, buf); 477ec681f3Smrg return result; 487ec681f3Smrg } 497ec681f3Smrg 507ec681f3Smrg /* TODO add a per-device cache for the requirements */ 517ec681f3Smrg buf->memory_requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; 527ec681f3Smrg buf->memory_requirements.pNext = &buf->dedicated_requirements; 537ec681f3Smrg buf->dedicated_requirements.sType = 547ec681f3Smrg VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; 557ec681f3Smrg buf->dedicated_requirements.pNext = NULL; 567ec681f3Smrg 577ec681f3Smrg vn_call_vkGetBufferMemoryRequirements2( 587ec681f3Smrg dev->instance, device, 597ec681f3Smrg &(VkBufferMemoryRequirementsInfo2){ 607ec681f3Smrg .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, 617ec681f3Smrg .buffer = buffer, 627ec681f3Smrg }, 637ec681f3Smrg &buf->memory_requirements); 647ec681f3Smrg 657ec681f3Smrg *out_buf = buf; 667ec681f3Smrg 677ec681f3Smrg return VK_SUCCESS; 687ec681f3Smrg} 697ec681f3Smrg 707ec681f3SmrgVkResult 717ec681f3Smrgvn_CreateBuffer(VkDevice device, 727ec681f3Smrg const VkBufferCreateInfo *pCreateInfo, 737ec681f3Smrg const VkAllocationCallbacks *pAllocator, 747ec681f3Smrg VkBuffer *pBuffer) 757ec681f3Smrg{ 767ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 777ec681f3Smrg const VkAllocationCallbacks *alloc = 787ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 797ec681f3Smrg struct vn_buffer *buf = NULL; 807ec681f3Smrg VkResult result; 817ec681f3Smrg 827ec681f3Smrg const VkExternalMemoryBufferCreateInfo *external_info = 837ec681f3Smrg vk_find_struct_const(pCreateInfo->pNext, 847ec681f3Smrg EXTERNAL_MEMORY_BUFFER_CREATE_INFO); 857ec681f3Smrg const bool ahb_info = 867ec681f3Smrg external_info && 877ec681f3Smrg external_info->handleTypes == 887ec681f3Smrg VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; 897ec681f3Smrg 907ec681f3Smrg if (ahb_info) 917ec681f3Smrg result = vn_android_buffer_from_ahb(dev, pCreateInfo, alloc, &buf); 927ec681f3Smrg else 937ec681f3Smrg result = vn_buffer_create(dev, pCreateInfo, alloc, &buf); 947ec681f3Smrg 957ec681f3Smrg if (result != VK_SUCCESS) 967ec681f3Smrg return vn_error(dev->instance, result); 977ec681f3Smrg 987ec681f3Smrg *pBuffer = vn_buffer_to_handle(buf); 997ec681f3Smrg 1007ec681f3Smrg return VK_SUCCESS; 1017ec681f3Smrg} 1027ec681f3Smrg 1037ec681f3Smrgvoid 1047ec681f3Smrgvn_DestroyBuffer(VkDevice device, 1057ec681f3Smrg VkBuffer buffer, 1067ec681f3Smrg const VkAllocationCallbacks *pAllocator) 1077ec681f3Smrg{ 1087ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 1097ec681f3Smrg struct vn_buffer *buf = vn_buffer_from_handle(buffer); 1107ec681f3Smrg const VkAllocationCallbacks *alloc = 1117ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 1127ec681f3Smrg 1137ec681f3Smrg if (!buf) 1147ec681f3Smrg return; 1157ec681f3Smrg 1167ec681f3Smrg vn_async_vkDestroyBuffer(dev->instance, device, buffer, NULL); 1177ec681f3Smrg 1187ec681f3Smrg vn_object_base_fini(&buf->base); 1197ec681f3Smrg vk_free(alloc, buf); 1207ec681f3Smrg} 1217ec681f3Smrg 1227ec681f3SmrgVkDeviceAddress 1237ec681f3Smrgvn_GetBufferDeviceAddress(VkDevice device, 1247ec681f3Smrg const VkBufferDeviceAddressInfo *pInfo) 1257ec681f3Smrg{ 1267ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 1277ec681f3Smrg 1287ec681f3Smrg return vn_call_vkGetBufferDeviceAddress(dev->instance, device, pInfo); 1297ec681f3Smrg} 1307ec681f3Smrg 1317ec681f3Smrguint64_t 1327ec681f3Smrgvn_GetBufferOpaqueCaptureAddress(VkDevice device, 1337ec681f3Smrg const VkBufferDeviceAddressInfo *pInfo) 1347ec681f3Smrg{ 1357ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 1367ec681f3Smrg 1377ec681f3Smrg return vn_call_vkGetBufferOpaqueCaptureAddress(dev->instance, device, 1387ec681f3Smrg pInfo); 1397ec681f3Smrg} 1407ec681f3Smrg 1417ec681f3Smrgvoid 1427ec681f3Smrgvn_GetBufferMemoryRequirements(VkDevice device, 1437ec681f3Smrg VkBuffer buffer, 1447ec681f3Smrg VkMemoryRequirements *pMemoryRequirements) 1457ec681f3Smrg{ 1467ec681f3Smrg const struct vn_buffer *buf = vn_buffer_from_handle(buffer); 1477ec681f3Smrg 1487ec681f3Smrg *pMemoryRequirements = buf->memory_requirements.memoryRequirements; 1497ec681f3Smrg} 1507ec681f3Smrg 1517ec681f3Smrgvoid 1527ec681f3Smrgvn_GetBufferMemoryRequirements2(VkDevice device, 1537ec681f3Smrg const VkBufferMemoryRequirementsInfo2 *pInfo, 1547ec681f3Smrg VkMemoryRequirements2 *pMemoryRequirements) 1557ec681f3Smrg{ 1567ec681f3Smrg const struct vn_buffer *buf = vn_buffer_from_handle(pInfo->buffer); 1577ec681f3Smrg union { 1587ec681f3Smrg VkBaseOutStructure *pnext; 1597ec681f3Smrg VkMemoryRequirements2 *two; 1607ec681f3Smrg VkMemoryDedicatedRequirements *dedicated; 1617ec681f3Smrg } u = { .two = pMemoryRequirements }; 1627ec681f3Smrg 1637ec681f3Smrg while (u.pnext) { 1647ec681f3Smrg switch (u.pnext->sType) { 1657ec681f3Smrg case VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2: 1667ec681f3Smrg u.two->memoryRequirements = 1677ec681f3Smrg buf->memory_requirements.memoryRequirements; 1687ec681f3Smrg break; 1697ec681f3Smrg case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: 1707ec681f3Smrg u.dedicated->prefersDedicatedAllocation = 1717ec681f3Smrg buf->dedicated_requirements.prefersDedicatedAllocation; 1727ec681f3Smrg u.dedicated->requiresDedicatedAllocation = 1737ec681f3Smrg buf->dedicated_requirements.requiresDedicatedAllocation; 1747ec681f3Smrg break; 1757ec681f3Smrg default: 1767ec681f3Smrg break; 1777ec681f3Smrg } 1787ec681f3Smrg u.pnext = u.pnext->pNext; 1797ec681f3Smrg } 1807ec681f3Smrg} 1817ec681f3Smrg 1827ec681f3SmrgVkResult 1837ec681f3Smrgvn_BindBufferMemory(VkDevice device, 1847ec681f3Smrg VkBuffer buffer, 1857ec681f3Smrg VkDeviceMemory memory, 1867ec681f3Smrg VkDeviceSize memoryOffset) 1877ec681f3Smrg{ 1887ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 1897ec681f3Smrg struct vn_device_memory *mem = vn_device_memory_from_handle(memory); 1907ec681f3Smrg 1917ec681f3Smrg if (mem->base_memory) { 1927ec681f3Smrg memory = vn_device_memory_to_handle(mem->base_memory); 1937ec681f3Smrg memoryOffset += mem->base_offset; 1947ec681f3Smrg } 1957ec681f3Smrg 1967ec681f3Smrg vn_async_vkBindBufferMemory(dev->instance, device, buffer, memory, 1977ec681f3Smrg memoryOffset); 1987ec681f3Smrg 1997ec681f3Smrg return VK_SUCCESS; 2007ec681f3Smrg} 2017ec681f3Smrg 2027ec681f3SmrgVkResult 2037ec681f3Smrgvn_BindBufferMemory2(VkDevice device, 2047ec681f3Smrg uint32_t bindInfoCount, 2057ec681f3Smrg const VkBindBufferMemoryInfo *pBindInfos) 2067ec681f3Smrg{ 2077ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 2087ec681f3Smrg const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 2097ec681f3Smrg 2107ec681f3Smrg VkBindBufferMemoryInfo *local_infos = NULL; 2117ec681f3Smrg for (uint32_t i = 0; i < bindInfoCount; i++) { 2127ec681f3Smrg const VkBindBufferMemoryInfo *info = &pBindInfos[i]; 2137ec681f3Smrg struct vn_device_memory *mem = 2147ec681f3Smrg vn_device_memory_from_handle(info->memory); 2157ec681f3Smrg if (!mem->base_memory) 2167ec681f3Smrg continue; 2177ec681f3Smrg 2187ec681f3Smrg if (!local_infos) { 2197ec681f3Smrg const size_t size = sizeof(*local_infos) * bindInfoCount; 2207ec681f3Smrg local_infos = vk_alloc(alloc, size, VN_DEFAULT_ALIGN, 2217ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 2227ec681f3Smrg if (!local_infos) 2237ec681f3Smrg return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 2247ec681f3Smrg 2257ec681f3Smrg memcpy(local_infos, pBindInfos, size); 2267ec681f3Smrg } 2277ec681f3Smrg 2287ec681f3Smrg local_infos[i].memory = vn_device_memory_to_handle(mem->base_memory); 2297ec681f3Smrg local_infos[i].memoryOffset += mem->base_offset; 2307ec681f3Smrg } 2317ec681f3Smrg if (local_infos) 2327ec681f3Smrg pBindInfos = local_infos; 2337ec681f3Smrg 2347ec681f3Smrg vn_async_vkBindBufferMemory2(dev->instance, device, bindInfoCount, 2357ec681f3Smrg pBindInfos); 2367ec681f3Smrg 2377ec681f3Smrg vk_free(alloc, local_infos); 2387ec681f3Smrg 2397ec681f3Smrg return VK_SUCCESS; 2407ec681f3Smrg} 2417ec681f3Smrg 2427ec681f3Smrg/* buffer view commands */ 2437ec681f3Smrg 2447ec681f3SmrgVkResult 2457ec681f3Smrgvn_CreateBufferView(VkDevice device, 2467ec681f3Smrg const VkBufferViewCreateInfo *pCreateInfo, 2477ec681f3Smrg const VkAllocationCallbacks *pAllocator, 2487ec681f3Smrg VkBufferView *pView) 2497ec681f3Smrg{ 2507ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 2517ec681f3Smrg const VkAllocationCallbacks *alloc = 2527ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 2537ec681f3Smrg 2547ec681f3Smrg struct vn_buffer_view *view = 2557ec681f3Smrg vk_zalloc(alloc, sizeof(*view), VN_DEFAULT_ALIGN, 2567ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 2577ec681f3Smrg if (!view) 2587ec681f3Smrg return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 2597ec681f3Smrg 2607ec681f3Smrg vn_object_base_init(&view->base, VK_OBJECT_TYPE_BUFFER_VIEW, &dev->base); 2617ec681f3Smrg 2627ec681f3Smrg VkBufferView view_handle = vn_buffer_view_to_handle(view); 2637ec681f3Smrg vn_async_vkCreateBufferView(dev->instance, device, pCreateInfo, NULL, 2647ec681f3Smrg &view_handle); 2657ec681f3Smrg 2667ec681f3Smrg *pView = view_handle; 2677ec681f3Smrg 2687ec681f3Smrg return VK_SUCCESS; 2697ec681f3Smrg} 2707ec681f3Smrg 2717ec681f3Smrgvoid 2727ec681f3Smrgvn_DestroyBufferView(VkDevice device, 2737ec681f3Smrg VkBufferView bufferView, 2747ec681f3Smrg const VkAllocationCallbacks *pAllocator) 2757ec681f3Smrg{ 2767ec681f3Smrg struct vn_device *dev = vn_device_from_handle(device); 2777ec681f3Smrg struct vn_buffer_view *view = vn_buffer_view_from_handle(bufferView); 2787ec681f3Smrg const VkAllocationCallbacks *alloc = 2797ec681f3Smrg pAllocator ? pAllocator : &dev->base.base.alloc; 2807ec681f3Smrg 2817ec681f3Smrg if (!view) 2827ec681f3Smrg return; 2837ec681f3Smrg 2847ec681f3Smrg vn_async_vkDestroyBufferView(dev->instance, device, bufferView, NULL); 2857ec681f3Smrg 2867ec681f3Smrg vn_object_base_fini(&view->base); 2877ec681f3Smrg vk_free(alloc, view); 2887ec681f3Smrg} 289