From: Karol Herbst Date: Fri, 20 May 2022 13:27:09 +0000 (+0200) Subject: nvk: add basic device memory support X-Git-Tag: upstream/23.3.3~4612 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=24641ecce4143fcf9b4ab6d29cb04978cc8e777c;p=platform%2Fupstream%2Fmesa.git nvk: add basic device memory support Part-of: --- diff --git a/src/nouveau/vulkan/meson.build b/src/nouveau/vulkan/meson.build index 8757f54..de93fa9 100644 --- a/src/nouveau/vulkan/meson.build +++ b/src/nouveau/vulkan/meson.build @@ -3,6 +3,8 @@ nvk_files = files( 'nvk_buffer.h', 'nvk_device.c', 'nvk_device.h', + 'nvk_device_memory.c', + 'nvk_device_memory.h', 'nvk_image.c', 'nvk_image.h', 'nvk_image_view.c', diff --git a/src/nouveau/vulkan/nvk_buffer.c b/src/nouveau/vulkan/nvk_buffer.c index ec15b96..ccd53fd 100644 --- a/src/nouveau/vulkan/nvk_buffer.c +++ b/src/nouveau/vulkan/nvk_buffer.c @@ -1,6 +1,7 @@ #include "nvk_buffer.h" #include "nvk_device.h" +#include "nvk_physical_device.h" VKAPI_ATTR VkResult VKAPI_CALL nvk_CreateBuffer(VkDevice _device, const VkBufferCreateInfo *pCreateInfo, @@ -31,3 +32,26 @@ VKAPI_ATTR void VKAPI_CALL nvk_DestroyBuffer(VkDevice _device, vk_buffer_destroy(&device->vk, pAllocator, &buffer->vk); } + +VKAPI_ATTR void VKAPI_CALL nvk_GetBufferMemoryRequirements2( + VkDevice _device, + const VkBufferMemoryRequirementsInfo2 *pInfo, + VkMemoryRequirements2 *pMemoryRequirements) +{ + VK_FROM_HANDLE(nvk_device, device, _device); + VK_FROM_HANDLE(nvk_buffer, buffer, pInfo->buffer); + + pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) { + .size = buffer->vk.size, + .alignment = 64, /* TODO */ + .memoryTypeBits = BITFIELD_MASK(device->pdev->mem_type_cnt), + }; + + vk_foreach_struct(ext, pMemoryRequirements->pNext) { + switch (ext->sType) { + default: + nvk_debug_ignored_stype(ext->sType); + break; + } + } +} diff --git a/src/nouveau/vulkan/nvk_device.c b/src/nouveau/vulkan/nvk_device.c index d64f4c3..7b8b9fd 100644 --- a/src/nouveau/vulkan/nvk_device.c +++ b/src/nouveau/vulkan/nvk_device.c @@ -32,6 +32,8 @@ nvk_CreateDevice(VkPhysicalDevice physicalDevice, if (result != VK_SUCCESS) goto fail_alloc; + device->pdev = physical_device; + *pDevice = nvk_device_to_handle(device); return VK_SUCCESS; diff --git a/src/nouveau/vulkan/nvk_device.h b/src/nouveau/vulkan/nvk_device.h index 95ba571..4991f71 100644 --- a/src/nouveau/vulkan/nvk_device.h +++ b/src/nouveau/vulkan/nvk_device.h @@ -5,8 +5,10 @@ #include "vulkan/runtime/vk_device.h" +struct nvk_physical_device; struct nvk_device { struct vk_device vk; + struct nvk_physical_device *pdev; }; VK_DEFINE_HANDLE_CASTS(nvk_device, vk.base, VkDevice, VK_OBJECT_TYPE_DEVICE) diff --git a/src/nouveau/vulkan/nvk_device_memory.c b/src/nouveau/vulkan/nvk_device_memory.c new file mode 100644 index 0000000..54e6c7a --- /dev/null +++ b/src/nouveau/vulkan/nvk_device_memory.c @@ -0,0 +1,151 @@ +#include "nvk_device_memory.h" + +#include "nouveau_bo.h" + +#include "nvk_device.h" +#include "nvk_physical_device.h" + +#include +#include + +VKAPI_ATTR VkResult VKAPI_CALL +nvk_AllocateMemory( + VkDevice _device, + const VkMemoryAllocateInfo *pAllocateInfo, + const VkAllocationCallbacks *pAllocator, + VkDeviceMemory *pMem) +{ + VK_FROM_HANDLE(nvk_device, device, _device); + VkMemoryType *type = &device->pdev->mem_types[pAllocateInfo->memoryTypeIndex]; + struct nvk_device_memory *mem; + + mem = vk_object_alloc(&device->vk, pAllocator, sizeof(*mem), VK_OBJECT_TYPE_DEVICE_MEMORY); + if (!mem) + return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + + enum nouveau_ws_bo_flags flags; + if (type->propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) + flags = NOUVEAU_WS_BO_LOCAL; + else + flags = NOUVEAU_WS_BO_GART; + + if (type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) + flags |= NOUVEAU_WS_BO_MAP; + + mem->map = NULL; + mem->bo = nouveau_ws_bo_new(device->pdev->dev, pAllocateInfo->allocationSize, 0, flags); + if (!mem->bo) { + vk_object_free(&device->vk, pAllocator, mem); + return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + *pMem = nvk_device_memory_to_handle(mem); + + return VK_SUCCESS; +} + +VKAPI_ATTR void VKAPI_CALL +nvk_FreeMemory( + VkDevice _device, + VkDeviceMemory _mem, + const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(nvk_device, device, _device); + VK_FROM_HANDLE(nvk_device_memory, mem, _mem); + + if (!mem) + return; + + if (mem->map) + nvk_UnmapMemory(_device, _mem); + + nouveau_ws_bo_destroy(mem->bo); + + vk_object_free(&device->vk, pAllocator, mem); +} + +VKAPI_ATTR VkResult VKAPI_CALL +nvk_MapMemory( + VkDevice _device, + VkDeviceMemory _memory, + VkDeviceSize offset, + VkDeviceSize size, + VkMemoryMapFlags flags, + void **ppData) +{ + VK_FROM_HANDLE(nvk_device, device, _device); + VK_FROM_HANDLE(nvk_device_memory, mem, _memory); + + if (mem == NULL) { + *ppData = NULL; + return VK_SUCCESS; + } + + if (size == VK_WHOLE_SIZE) + size = mem->bo->size - offset; + + /* From the Vulkan spec version 1.0.32 docs for MapMemory: + * + * * If size is not equal to VK_WHOLE_SIZE, size must be greater than 0 + * assert(size != 0); + * * If size is not equal to VK_WHOLE_SIZE, size must be less than or + * equal to the size of the memory minus offset + */ + assert(size > 0); + assert(offset + size <= mem->bo->size); + + if (size != (size_t)size) { + return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED, + "requested size 0x%"PRIx64" does not fit in %u bits", + size, (unsigned)(sizeof(size_t) * 8)); + } + + /* From the Vulkan 1.2.194 spec: + * + * "memory must not be currently host mapped" + */ + if (mem->map != NULL) { + return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED, "Memory object already mapped."); + } + + mem->map = nouveau_ws_bo_map(mem->bo, NOUVEAU_WS_BO_RDWR); + if (mem->map == NULL) { + return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED, "Memory object couldn't be mapped."); + } + + *ppData = mem->map + offset; + + return VK_SUCCESS; +} + +VKAPI_ATTR void VKAPI_CALL +nvk_UnmapMemory( + VkDevice _device, + VkDeviceMemory _memory) +{ + VK_FROM_HANDLE(nvk_device_memory, mem, _memory); + + if (mem == NULL) + return; + + munmap(mem->map, mem->bo->size); + mem->map = NULL; +} + +VKAPI_ATTR VkResult VKAPI_CALL +nvk_FlushMappedMemoryRanges( + VkDevice _device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange *pMemoryRanges) +{ + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult VKAPI_CALL +nvk_InvalidateMappedMemoryRanges( + VkDevice _device, + uint32_t memoryRangeCount, + const VkMappedMemoryRange *pMemoryRanges) +{ + return VK_SUCCESS; +} diff --git a/src/nouveau/vulkan/nvk_device_memory.h b/src/nouveau/vulkan/nvk_device_memory.h new file mode 100644 index 0000000..14749c6 --- /dev/null +++ b/src/nouveau/vulkan/nvk_device_memory.h @@ -0,0 +1,16 @@ +#ifndef NVK_MEMORY +#define NVK_MEMORY 1 + +#include "nvk_private.h" + +struct nvk_device_memory { + struct vk_object_base base; + + struct nouveau_ws_bo *bo; + + void *map; +}; + +VK_DEFINE_HANDLE_CASTS(nvk_device_memory, base, VkDeviceMemory, VK_OBJECT_TYPE_DEVICE_MEMORY) + +#endif diff --git a/src/nouveau/vulkan/nvk_image.c b/src/nouveau/vulkan/nvk_image.c index b1aaf2a..74df875 100644 --- a/src/nouveau/vulkan/nvk_image.c +++ b/src/nouveau/vulkan/nvk_image.c @@ -53,3 +53,17 @@ VKAPI_ATTR void VKAPI_CALL nvk_DestroyImage(VkDevice _device, nvk_image_finish(image); vk_free2(&device->vk.alloc, pAllocator, image); } + +VKAPI_ATTR void VKAPI_CALL nvk_GetImageMemoryRequirements2( + VkDevice _device, + const VkImageMemoryRequirementsInfo2 *pInfo, + VkMemoryRequirements2 *pMemoryRequirements) +{ + vk_foreach_struct_const(ext, pInfo->pNext) { + switch (ext->sType) { + default: + nvk_debug_ignored_stype(ext->sType); + break; + } + } +}