nvk: add basic device memory support
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24326>
This commit is contained in:
@@ -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',
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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)
|
||||
|
151
src/nouveau/vulkan/nvk_device_memory.c
Normal file
151
src/nouveau/vulkan/nvk_device_memory.c
Normal file
@@ -0,0 +1,151 @@
|
||||
#include "nvk_device_memory.h"
|
||||
|
||||
#include "nouveau_bo.h"
|
||||
|
||||
#include "nvk_device.h"
|
||||
#include "nvk_physical_device.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
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;
|
||||
}
|
16
src/nouveau/vulkan/nvk_device_memory.h
Normal file
16
src/nouveau/vulkan/nvk_device_memory.h
Normal file
@@ -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
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user