vn_buffer.c revision 7ec681f3
1/* 2 * Copyright 2019 Google LLC 3 * SPDX-License-Identifier: MIT 4 * 5 * based in part on anv and radv which are: 6 * Copyright © 2015 Intel Corporation 7 * Copyright © 2016 Red Hat. 8 * Copyright © 2016 Bas Nieuwenhuizen 9 */ 10 11#include "vn_buffer.h" 12 13#include "venus-protocol/vn_protocol_driver_buffer.h" 14#include "venus-protocol/vn_protocol_driver_buffer_view.h" 15 16#include "vn_android.h" 17#include "vn_device.h" 18#include "vn_device_memory.h" 19 20/* buffer commands */ 21 22VkResult 23vn_buffer_create(struct vn_device *dev, 24 const VkBufferCreateInfo *create_info, 25 const VkAllocationCallbacks *alloc, 26 struct vn_buffer **out_buf) 27{ 28 VkDevice device = vn_device_to_handle(dev); 29 struct vn_buffer *buf = NULL; 30 VkBuffer buffer = VK_NULL_HANDLE; 31 VkResult result; 32 33 buf = vk_zalloc(alloc, sizeof(*buf), VN_DEFAULT_ALIGN, 34 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 35 if (!buf) 36 return VK_ERROR_OUT_OF_HOST_MEMORY; 37 38 vn_object_base_init(&buf->base, VK_OBJECT_TYPE_BUFFER, &dev->base); 39 40 buffer = vn_buffer_to_handle(buf); 41 /* TODO async */ 42 result = vn_call_vkCreateBuffer(dev->instance, device, create_info, NULL, 43 &buffer); 44 if (result != VK_SUCCESS) { 45 vn_object_base_fini(&buf->base); 46 vk_free(alloc, buf); 47 return result; 48 } 49 50 /* TODO add a per-device cache for the requirements */ 51 buf->memory_requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2; 52 buf->memory_requirements.pNext = &buf->dedicated_requirements; 53 buf->dedicated_requirements.sType = 54 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS; 55 buf->dedicated_requirements.pNext = NULL; 56 57 vn_call_vkGetBufferMemoryRequirements2( 58 dev->instance, device, 59 &(VkBufferMemoryRequirementsInfo2){ 60 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, 61 .buffer = buffer, 62 }, 63 &buf->memory_requirements); 64 65 *out_buf = buf; 66 67 return VK_SUCCESS; 68} 69 70VkResult 71vn_CreateBuffer(VkDevice device, 72 const VkBufferCreateInfo *pCreateInfo, 73 const VkAllocationCallbacks *pAllocator, 74 VkBuffer *pBuffer) 75{ 76 struct vn_device *dev = vn_device_from_handle(device); 77 const VkAllocationCallbacks *alloc = 78 pAllocator ? pAllocator : &dev->base.base.alloc; 79 struct vn_buffer *buf = NULL; 80 VkResult result; 81 82 const VkExternalMemoryBufferCreateInfo *external_info = 83 vk_find_struct_const(pCreateInfo->pNext, 84 EXTERNAL_MEMORY_BUFFER_CREATE_INFO); 85 const bool ahb_info = 86 external_info && 87 external_info->handleTypes == 88 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; 89 90 if (ahb_info) 91 result = vn_android_buffer_from_ahb(dev, pCreateInfo, alloc, &buf); 92 else 93 result = vn_buffer_create(dev, pCreateInfo, alloc, &buf); 94 95 if (result != VK_SUCCESS) 96 return vn_error(dev->instance, result); 97 98 *pBuffer = vn_buffer_to_handle(buf); 99 100 return VK_SUCCESS; 101} 102 103void 104vn_DestroyBuffer(VkDevice device, 105 VkBuffer buffer, 106 const VkAllocationCallbacks *pAllocator) 107{ 108 struct vn_device *dev = vn_device_from_handle(device); 109 struct vn_buffer *buf = vn_buffer_from_handle(buffer); 110 const VkAllocationCallbacks *alloc = 111 pAllocator ? pAllocator : &dev->base.base.alloc; 112 113 if (!buf) 114 return; 115 116 vn_async_vkDestroyBuffer(dev->instance, device, buffer, NULL); 117 118 vn_object_base_fini(&buf->base); 119 vk_free(alloc, buf); 120} 121 122VkDeviceAddress 123vn_GetBufferDeviceAddress(VkDevice device, 124 const VkBufferDeviceAddressInfo *pInfo) 125{ 126 struct vn_device *dev = vn_device_from_handle(device); 127 128 return vn_call_vkGetBufferDeviceAddress(dev->instance, device, pInfo); 129} 130 131uint64_t 132vn_GetBufferOpaqueCaptureAddress(VkDevice device, 133 const VkBufferDeviceAddressInfo *pInfo) 134{ 135 struct vn_device *dev = vn_device_from_handle(device); 136 137 return vn_call_vkGetBufferOpaqueCaptureAddress(dev->instance, device, 138 pInfo); 139} 140 141void 142vn_GetBufferMemoryRequirements(VkDevice device, 143 VkBuffer buffer, 144 VkMemoryRequirements *pMemoryRequirements) 145{ 146 const struct vn_buffer *buf = vn_buffer_from_handle(buffer); 147 148 *pMemoryRequirements = buf->memory_requirements.memoryRequirements; 149} 150 151void 152vn_GetBufferMemoryRequirements2(VkDevice device, 153 const VkBufferMemoryRequirementsInfo2 *pInfo, 154 VkMemoryRequirements2 *pMemoryRequirements) 155{ 156 const struct vn_buffer *buf = vn_buffer_from_handle(pInfo->buffer); 157 union { 158 VkBaseOutStructure *pnext; 159 VkMemoryRequirements2 *two; 160 VkMemoryDedicatedRequirements *dedicated; 161 } u = { .two = pMemoryRequirements }; 162 163 while (u.pnext) { 164 switch (u.pnext->sType) { 165 case VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2: 166 u.two->memoryRequirements = 167 buf->memory_requirements.memoryRequirements; 168 break; 169 case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: 170 u.dedicated->prefersDedicatedAllocation = 171 buf->dedicated_requirements.prefersDedicatedAllocation; 172 u.dedicated->requiresDedicatedAllocation = 173 buf->dedicated_requirements.requiresDedicatedAllocation; 174 break; 175 default: 176 break; 177 } 178 u.pnext = u.pnext->pNext; 179 } 180} 181 182VkResult 183vn_BindBufferMemory(VkDevice device, 184 VkBuffer buffer, 185 VkDeviceMemory memory, 186 VkDeviceSize memoryOffset) 187{ 188 struct vn_device *dev = vn_device_from_handle(device); 189 struct vn_device_memory *mem = vn_device_memory_from_handle(memory); 190 191 if (mem->base_memory) { 192 memory = vn_device_memory_to_handle(mem->base_memory); 193 memoryOffset += mem->base_offset; 194 } 195 196 vn_async_vkBindBufferMemory(dev->instance, device, buffer, memory, 197 memoryOffset); 198 199 return VK_SUCCESS; 200} 201 202VkResult 203vn_BindBufferMemory2(VkDevice device, 204 uint32_t bindInfoCount, 205 const VkBindBufferMemoryInfo *pBindInfos) 206{ 207 struct vn_device *dev = vn_device_from_handle(device); 208 const VkAllocationCallbacks *alloc = &dev->base.base.alloc; 209 210 VkBindBufferMemoryInfo *local_infos = NULL; 211 for (uint32_t i = 0; i < bindInfoCount; i++) { 212 const VkBindBufferMemoryInfo *info = &pBindInfos[i]; 213 struct vn_device_memory *mem = 214 vn_device_memory_from_handle(info->memory); 215 if (!mem->base_memory) 216 continue; 217 218 if (!local_infos) { 219 const size_t size = sizeof(*local_infos) * bindInfoCount; 220 local_infos = vk_alloc(alloc, size, VN_DEFAULT_ALIGN, 221 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND); 222 if (!local_infos) 223 return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 224 225 memcpy(local_infos, pBindInfos, size); 226 } 227 228 local_infos[i].memory = vn_device_memory_to_handle(mem->base_memory); 229 local_infos[i].memoryOffset += mem->base_offset; 230 } 231 if (local_infos) 232 pBindInfos = local_infos; 233 234 vn_async_vkBindBufferMemory2(dev->instance, device, bindInfoCount, 235 pBindInfos); 236 237 vk_free(alloc, local_infos); 238 239 return VK_SUCCESS; 240} 241 242/* buffer view commands */ 243 244VkResult 245vn_CreateBufferView(VkDevice device, 246 const VkBufferViewCreateInfo *pCreateInfo, 247 const VkAllocationCallbacks *pAllocator, 248 VkBufferView *pView) 249{ 250 struct vn_device *dev = vn_device_from_handle(device); 251 const VkAllocationCallbacks *alloc = 252 pAllocator ? pAllocator : &dev->base.base.alloc; 253 254 struct vn_buffer_view *view = 255 vk_zalloc(alloc, sizeof(*view), VN_DEFAULT_ALIGN, 256 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 257 if (!view) 258 return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); 259 260 vn_object_base_init(&view->base, VK_OBJECT_TYPE_BUFFER_VIEW, &dev->base); 261 262 VkBufferView view_handle = vn_buffer_view_to_handle(view); 263 vn_async_vkCreateBufferView(dev->instance, device, pCreateInfo, NULL, 264 &view_handle); 265 266 *pView = view_handle; 267 268 return VK_SUCCESS; 269} 270 271void 272vn_DestroyBufferView(VkDevice device, 273 VkBufferView bufferView, 274 const VkAllocationCallbacks *pAllocator) 275{ 276 struct vn_device *dev = vn_device_from_handle(device); 277 struct vn_buffer_view *view = vn_buffer_view_from_handle(bufferView); 278 const VkAllocationCallbacks *alloc = 279 pAllocator ? pAllocator : &dev->base.base.alloc; 280 281 if (!view) 282 return; 283 284 vn_async_vkDestroyBufferView(dev->instance, device, bufferView, NULL); 285 286 vn_object_base_fini(&view->base); 287 vk_free(alloc, view); 288} 289