Path: blob/21.2-virgl/src/virtio/vulkan/vn_buffer.c
4560 views
/*1* Copyright 2019 Google LLC2* SPDX-License-Identifier: MIT3*4* based in part on anv and radv which are:5* Copyright © 2015 Intel Corporation6* Copyright © 2016 Red Hat.7* Copyright © 2016 Bas Nieuwenhuizen8*/910#include "vn_buffer.h"1112#include "venus-protocol/vn_protocol_driver_buffer.h"13#include "venus-protocol/vn_protocol_driver_buffer_view.h"1415#include "vn_android.h"16#include "vn_device.h"17#include "vn_device_memory.h"1819/* buffer commands */2021VkResult22vn_buffer_create(struct vn_device *dev,23const VkBufferCreateInfo *create_info,24const VkAllocationCallbacks *alloc,25struct vn_buffer **out_buf)26{27VkDevice device = vn_device_to_handle(dev);28struct vn_buffer *buf = NULL;29VkBuffer buffer = VK_NULL_HANDLE;30VkResult result;3132buf = vk_zalloc(alloc, sizeof(*buf), VN_DEFAULT_ALIGN,33VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);34if (!buf)35return VK_ERROR_OUT_OF_HOST_MEMORY;3637vn_object_base_init(&buf->base, VK_OBJECT_TYPE_BUFFER, &dev->base);3839buffer = vn_buffer_to_handle(buf);40/* TODO async */41result = vn_call_vkCreateBuffer(dev->instance, device, create_info, NULL,42&buffer);43if (result != VK_SUCCESS) {44vk_free(alloc, buf);45return result;46}4748/* TODO add a per-device cache for the requirements */49buf->memory_requirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;50buf->memory_requirements.pNext = &buf->dedicated_requirements;51buf->dedicated_requirements.sType =52VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;53buf->dedicated_requirements.pNext = NULL;5455vn_call_vkGetBufferMemoryRequirements2(56dev->instance, device,57&(VkBufferMemoryRequirementsInfo2){58.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,59.buffer = buffer,60},61&buf->memory_requirements);6263*out_buf = buf;6465return VK_SUCCESS;66}6768VkResult69vn_CreateBuffer(VkDevice device,70const VkBufferCreateInfo *pCreateInfo,71const VkAllocationCallbacks *pAllocator,72VkBuffer *pBuffer)73{74struct vn_device *dev = vn_device_from_handle(device);75const VkAllocationCallbacks *alloc =76pAllocator ? pAllocator : &dev->base.base.alloc;77struct vn_buffer *buf = NULL;78VkResult result;7980const VkExternalMemoryBufferCreateInfo *external_info =81vk_find_struct_const(pCreateInfo->pNext,82EXTERNAL_MEMORY_BUFFER_CREATE_INFO);83const bool ahb_info =84external_info &&85external_info->handleTypes ==86VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;8788if (ahb_info)89result = vn_android_buffer_from_ahb(dev, pCreateInfo, alloc, &buf);90else91result = vn_buffer_create(dev, pCreateInfo, alloc, &buf);9293if (result != VK_SUCCESS)94return vn_error(dev->instance, result);9596*pBuffer = vn_buffer_to_handle(buf);9798return VK_SUCCESS;99}100101void102vn_DestroyBuffer(VkDevice device,103VkBuffer buffer,104const VkAllocationCallbacks *pAllocator)105{106struct vn_device *dev = vn_device_from_handle(device);107struct vn_buffer *buf = vn_buffer_from_handle(buffer);108const VkAllocationCallbacks *alloc =109pAllocator ? pAllocator : &dev->base.base.alloc;110111if (!buf)112return;113114vn_async_vkDestroyBuffer(dev->instance, device, buffer, NULL);115116vn_object_base_fini(&buf->base);117vk_free(alloc, buf);118}119120VkDeviceAddress121vn_GetBufferDeviceAddress(VkDevice device,122const VkBufferDeviceAddressInfo *pInfo)123{124struct vn_device *dev = vn_device_from_handle(device);125126return vn_call_vkGetBufferDeviceAddress(dev->instance, device, pInfo);127}128129uint64_t130vn_GetBufferOpaqueCaptureAddress(VkDevice device,131const VkBufferDeviceAddressInfo *pInfo)132{133struct vn_device *dev = vn_device_from_handle(device);134135return vn_call_vkGetBufferOpaqueCaptureAddress(dev->instance, device,136pInfo);137}138139void140vn_GetBufferMemoryRequirements(VkDevice device,141VkBuffer buffer,142VkMemoryRequirements *pMemoryRequirements)143{144const struct vn_buffer *buf = vn_buffer_from_handle(buffer);145146*pMemoryRequirements = buf->memory_requirements.memoryRequirements;147}148149void150vn_GetBufferMemoryRequirements2(VkDevice device,151const VkBufferMemoryRequirementsInfo2 *pInfo,152VkMemoryRequirements2 *pMemoryRequirements)153{154const struct vn_buffer *buf = vn_buffer_from_handle(pInfo->buffer);155union {156VkBaseOutStructure *pnext;157VkMemoryRequirements2 *two;158VkMemoryDedicatedRequirements *dedicated;159} u = { .two = pMemoryRequirements };160161while (u.pnext) {162switch (u.pnext->sType) {163case VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2:164u.two->memoryRequirements =165buf->memory_requirements.memoryRequirements;166break;167case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS:168u.dedicated->prefersDedicatedAllocation =169buf->dedicated_requirements.prefersDedicatedAllocation;170u.dedicated->requiresDedicatedAllocation =171buf->dedicated_requirements.requiresDedicatedAllocation;172break;173default:174break;175}176u.pnext = u.pnext->pNext;177}178}179180VkResult181vn_BindBufferMemory(VkDevice device,182VkBuffer buffer,183VkDeviceMemory memory,184VkDeviceSize memoryOffset)185{186struct vn_device *dev = vn_device_from_handle(device);187struct vn_device_memory *mem = vn_device_memory_from_handle(memory);188189if (mem->base_memory) {190memory = vn_device_memory_to_handle(mem->base_memory);191memoryOffset += mem->base_offset;192}193194vn_async_vkBindBufferMemory(dev->instance, device, buffer, memory,195memoryOffset);196197return VK_SUCCESS;198}199200VkResult201vn_BindBufferMemory2(VkDevice device,202uint32_t bindInfoCount,203const VkBindBufferMemoryInfo *pBindInfos)204{205struct vn_device *dev = vn_device_from_handle(device);206const VkAllocationCallbacks *alloc = &dev->base.base.alloc;207208VkBindBufferMemoryInfo *local_infos = NULL;209for (uint32_t i = 0; i < bindInfoCount; i++) {210const VkBindBufferMemoryInfo *info = &pBindInfos[i];211struct vn_device_memory *mem =212vn_device_memory_from_handle(info->memory);213if (!mem->base_memory)214continue;215216if (!local_infos) {217const size_t size = sizeof(*local_infos) * bindInfoCount;218local_infos = vk_alloc(alloc, size, VN_DEFAULT_ALIGN,219VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);220if (!local_infos)221return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);222223memcpy(local_infos, pBindInfos, size);224}225226local_infos[i].memory = vn_device_memory_to_handle(mem->base_memory);227local_infos[i].memoryOffset += mem->base_offset;228}229if (local_infos)230pBindInfos = local_infos;231232vn_async_vkBindBufferMemory2(dev->instance, device, bindInfoCount,233pBindInfos);234235vk_free(alloc, local_infos);236237return VK_SUCCESS;238}239240/* buffer view commands */241242VkResult243vn_CreateBufferView(VkDevice device,244const VkBufferViewCreateInfo *pCreateInfo,245const VkAllocationCallbacks *pAllocator,246VkBufferView *pView)247{248struct vn_device *dev = vn_device_from_handle(device);249const VkAllocationCallbacks *alloc =250pAllocator ? pAllocator : &dev->base.base.alloc;251252struct vn_buffer_view *view =253vk_zalloc(alloc, sizeof(*view), VN_DEFAULT_ALIGN,254VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);255if (!view)256return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);257258vn_object_base_init(&view->base, VK_OBJECT_TYPE_BUFFER_VIEW, &dev->base);259260VkBufferView view_handle = vn_buffer_view_to_handle(view);261vn_async_vkCreateBufferView(dev->instance, device, pCreateInfo, NULL,262&view_handle);263264*pView = view_handle;265266return VK_SUCCESS;267}268269void270vn_DestroyBufferView(VkDevice device,271VkBufferView bufferView,272const VkAllocationCallbacks *pAllocator)273{274struct vn_device *dev = vn_device_from_handle(device);275struct vn_buffer_view *view = vn_buffer_view_from_handle(bufferView);276const VkAllocationCallbacks *alloc =277pAllocator ? pAllocator : &dev->base.base.alloc;278279if (!view)280return;281282vn_async_vkDestroyBufferView(dev->instance, device, bufferView, NULL);283284vn_object_base_fini(&view->base);285vk_free(alloc, view);286}287288289