diff --git a/src/panfrost/vulkan/meson.build b/src/panfrost/vulkan/meson.build index 7ea27333740..828bb11adeb 100644 --- a/src/panfrost/vulkan/meson.build +++ b/src/panfrost/vulkan/meson.build @@ -35,6 +35,7 @@ panvk_entrypoints = custom_target( ) libpanvk_files = files( + 'panvk_buffer.c', 'panvk_cmd_buffer.c', 'panvk_cs.c', 'panvk_device.c', diff --git a/src/panfrost/vulkan/panvk_buffer.c b/src/panfrost/vulkan/panvk_buffer.c new file mode 100644 index 00000000000..b55fe9704e7 --- /dev/null +++ b/src/panfrost/vulkan/panvk_buffer.c @@ -0,0 +1,114 @@ +/* + * Copyright © 2021 Collabora Ltd. + * SPDX-License-Identifier: MIT + */ + +#include "panvk_buffer.h" +#include "panvk_private.h" + +VKAPI_ATTR VkDeviceAddress VKAPI_CALL +panvk_GetBufferDeviceAddress(VkDevice _device, + const VkBufferDeviceAddressInfo *pInfo) +{ + VK_FROM_HANDLE(panvk_buffer, buffer, pInfo->buffer); + + return buffer->dev_addr; +} + +VKAPI_ATTR void VKAPI_CALL +panvk_GetBufferMemoryRequirements2(VkDevice device, + const VkBufferMemoryRequirementsInfo2 *pInfo, + VkMemoryRequirements2 *pMemoryRequirements) +{ + VK_FROM_HANDLE(panvk_buffer, buffer, pInfo->buffer); + + const uint64_t align = 64; + const uint64_t size = align64(buffer->vk.size, align); + + pMemoryRequirements->memoryRequirements.memoryTypeBits = 1; + pMemoryRequirements->memoryRequirements.alignment = align; + pMemoryRequirements->memoryRequirements.size = size; +} + +VKAPI_ATTR VkResult VKAPI_CALL +panvk_BindBufferMemory2(VkDevice device, uint32_t bindInfoCount, + const VkBindBufferMemoryInfo *pBindInfos) +{ + for (uint32_t i = 0; i < bindInfoCount; ++i) { + VK_FROM_HANDLE(panvk_device_memory, mem, pBindInfos[i].memory); + VK_FROM_HANDLE(panvk_buffer, buffer, pBindInfos[i].buffer); + struct pan_kmod_bo *old_bo = buffer->bo; + + assert(mem != NULL); + + buffer->bo = pan_kmod_bo_get(mem->bo); + buffer->dev_addr = mem->addr.dev + pBindInfos[i].memoryOffset; + + /* FIXME: Only host map for index buffers so we can do the min/max + * index retrieval on the CPU. This is all broken anyway and the + * min/max search should be done with a compute shader that also + * patches the job descriptor accordingly (basically an indirect draw). + * + * Make sure this goes away as soon as we fixed indirect draws. + */ + if (buffer->vk.usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) { + VkDeviceSize offset = pBindInfos[i].memoryOffset; + VkDeviceSize pgsize = getpagesize(); + off_t map_start = offset & ~(pgsize - 1); + off_t map_end = offset + buffer->vk.size; + void *map_addr = + pan_kmod_bo_mmap(mem->bo, map_start, map_end - map_start, + PROT_WRITE, MAP_SHARED, NULL); + + assert(map_addr != MAP_FAILED); + buffer->host_ptr = map_addr + (offset & pgsize); + } + + pan_kmod_bo_put(old_bo); + } + return VK_SUCCESS; +} + +VKAPI_ATTR VkResult VKAPI_CALL +panvk_CreateBuffer(VkDevice _device, const VkBufferCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) +{ + VK_FROM_HANDLE(panvk_device, device, _device); + struct panvk_buffer *buffer; + + assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO); + + buffer = + vk_buffer_create(&device->vk, pCreateInfo, pAllocator, sizeof(*buffer)); + if (buffer == NULL) + return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); + + *pBuffer = panvk_buffer_to_handle(buffer); + + return VK_SUCCESS; +} + +VKAPI_ATTR void VKAPI_CALL +panvk_DestroyBuffer(VkDevice _device, VkBuffer _buffer, + const VkAllocationCallbacks *pAllocator) +{ + VK_FROM_HANDLE(panvk_device, device, _device); + VK_FROM_HANDLE(panvk_buffer, buffer, _buffer); + + if (!buffer) + return; + + if (buffer->host_ptr) { + VkDeviceSize pgsize = getpagesize(); + uintptr_t map_start = (uintptr_t)buffer->host_ptr & ~(pgsize - 1); + uintptr_t map_end = + ALIGN_POT((uintptr_t)buffer->host_ptr + buffer->vk.size, pgsize); + ASSERTED int ret = os_munmap((void *)map_start, map_end - map_start); + + assert(!ret); + buffer->host_ptr = NULL; + } + + pan_kmod_bo_put(buffer->bo); + vk_buffer_destroy(&device->vk, pAllocator, &buffer->vk); +} diff --git a/src/panfrost/vulkan/panvk_buffer.h b/src/panfrost/vulkan/panvk_buffer.h new file mode 100644 index 00000000000..741b31de64b --- /dev/null +++ b/src/panfrost/vulkan/panvk_buffer.h @@ -0,0 +1,57 @@ +/* + * Copyright © 2021 Collabora Ltd. + * SPDX-License-Identifier: MIT + */ + +#ifndef PANVK_BUFFER_H +#define PANVK_BUFFER_H + +#include + +#include "vk_buffer.h" + +struct panvk_priv_bo; + +struct panvk_buffer { + struct vk_buffer vk; + + uint64_t dev_addr; + + /* TODO: See if we can rework the synchronization logic so we don't need to + * pass BOs around. + */ + struct pan_kmod_bo *bo; + + /* FIXME: Only used for index buffers to do the min/max index retrieval on + * the CPU. This is all broken anyway and the min/max search should be done + * with a compute shader that also patches the job descriptor accordingly + * (basically an indirect draw). + * + * Make sure this field goes away as soon as we fixed indirect draws. + */ + void *host_ptr; +}; + +VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_buffer, vk.base, VkBuffer, + VK_OBJECT_TYPE_BUFFER) + +static inline uint64_t +panvk_buffer_gpu_ptr(const struct panvk_buffer *buffer, uint64_t offset) +{ + if (buffer->bo == NULL) + return 0; + + return buffer->dev_addr + offset; +} + +static inline uint64_t +panvk_buffer_range(const struct panvk_buffer *buffer, uint64_t offset, + uint64_t range) +{ + if (buffer->bo == NULL) + return 0; + + return vk_buffer_range(&buffer->vk, offset, range); +} + +#endif diff --git a/src/panfrost/vulkan/panvk_cmd_buffer.c b/src/panfrost/vulkan/panvk_cmd_buffer.c index 61987c30eaa..e6beb294666 100644 --- a/src/panfrost/vulkan/panvk_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_cmd_buffer.c @@ -26,6 +26,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include "panvk_buffer.h" #include "panvk_private.h" #include "pan_encoder.h" diff --git a/src/panfrost/vulkan/panvk_device.c b/src/panfrost/vulkan/panvk_device.c index ce0a869a9dc..3f5ba6374e7 100644 --- a/src/panfrost/vulkan/panvk_device.c +++ b/src/panfrost/vulkan/panvk_device.c @@ -1550,30 +1550,6 @@ panvk_InvalidateMappedMemoryRanges(VkDevice _device, uint32_t memoryRangeCount, return VK_SUCCESS; } -VKAPI_ATTR VkDeviceAddress VKAPI_CALL -panvk_GetBufferDeviceAddress(VkDevice _device, - const VkBufferDeviceAddressInfo *pInfo) -{ - VK_FROM_HANDLE(panvk_buffer, buffer, pInfo->buffer); - - return buffer->dev_addr; -} - -VKAPI_ATTR void VKAPI_CALL -panvk_GetBufferMemoryRequirements2(VkDevice device, - const VkBufferMemoryRequirementsInfo2 *pInfo, - VkMemoryRequirements2 *pMemoryRequirements) -{ - VK_FROM_HANDLE(panvk_buffer, buffer, pInfo->buffer); - - const uint64_t alignment = 64; - const uint64_t size = align64(buffer->vk.size, alignment); - - pMemoryRequirements->memoryRequirements.memoryTypeBits = 1; - pMemoryRequirements->memoryRequirements.alignment = alignment; - pMemoryRequirements->memoryRequirements.size = size; -} - VKAPI_ATTR void VKAPI_CALL panvk_GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, VkDeviceSize *pCommittedMemoryInBytes) @@ -1581,45 +1557,6 @@ panvk_GetDeviceMemoryCommitment(VkDevice device, VkDeviceMemory memory, *pCommittedMemoryInBytes = 0; } -VKAPI_ATTR VkResult VKAPI_CALL -panvk_BindBufferMemory2(VkDevice device, uint32_t bindInfoCount, - const VkBindBufferMemoryInfo *pBindInfos) -{ - for (uint32_t i = 0; i < bindInfoCount; ++i) { - VK_FROM_HANDLE(panvk_device_memory, mem, pBindInfos[i].memory); - VK_FROM_HANDLE(panvk_buffer, buffer, pBindInfos[i].buffer); - struct pan_kmod_bo *old_bo = buffer->bo; - - assert(mem != NULL); - - buffer->bo = pan_kmod_bo_get(mem->bo); - buffer->dev_addr = mem->addr.dev + pBindInfos[i].memoryOffset; - - /* FIXME: Only host map for index buffers so we can do the min/max - * index retrieval on the CPU. This is all broken anyway and the - * min/max search should be done with a compute shader that also - * patches the job descriptor accordingly (basically an indirect draw). - * - * Make sure this goes away as soon as we fixed indirect draws. - */ - if (buffer->vk.usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) { - VkDeviceSize offset = pBindInfos[i].memoryOffset; - VkDeviceSize pgsize = getpagesize(); - off_t map_start = offset & ~(pgsize - 1); - off_t map_end = offset + buffer->vk.size; - void *map_addr = - pan_kmod_bo_mmap(mem->bo, map_start, map_end - map_start, - PROT_WRITE, MAP_SHARED, NULL); - - assert(map_addr != MAP_FAILED); - buffer->host_ptr = map_addr + (offset & pgsize); - } - - pan_kmod_bo_put(old_bo); - } - return VK_SUCCESS; -} - VKAPI_ATTR VkResult VKAPI_CALL panvk_CreateEvent(VkDevice _device, const VkEventCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkEvent *pEvent) @@ -1726,50 +1663,6 @@ panvk_ResetEvent(VkDevice _device, VkEvent _event) return VK_SUCCESS; } -VKAPI_ATTR VkResult VKAPI_CALL -panvk_CreateBuffer(VkDevice _device, const VkBufferCreateInfo *pCreateInfo, - const VkAllocationCallbacks *pAllocator, VkBuffer *pBuffer) -{ - VK_FROM_HANDLE(panvk_device, device, _device); - struct panvk_buffer *buffer; - - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO); - - buffer = - vk_buffer_create(&device->vk, pCreateInfo, pAllocator, sizeof(*buffer)); - if (buffer == NULL) - return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); - - *pBuffer = panvk_buffer_to_handle(buffer); - - return VK_SUCCESS; -} - -VKAPI_ATTR void VKAPI_CALL -panvk_DestroyBuffer(VkDevice _device, VkBuffer _buffer, - const VkAllocationCallbacks *pAllocator) -{ - VK_FROM_HANDLE(panvk_device, device, _device); - VK_FROM_HANDLE(panvk_buffer, buffer, _buffer); - - if (!buffer) - return; - - if (buffer->host_ptr) { - VkDeviceSize pgsize = getpagesize(); - uintptr_t map_start = (uintptr_t)buffer->host_ptr & ~(pgsize - 1); - uintptr_t map_end = - ALIGN_POT((uintptr_t)buffer->host_ptr + buffer->vk.size, pgsize); - ASSERTED int ret = os_munmap((void *)map_start, map_end - map_start); - - assert(!ret); - buffer->host_ptr = NULL; - } - - pan_kmod_bo_put(buffer->bo); - vk_buffer_destroy(&device->vk, pAllocator, &buffer->vk); -} - VKAPI_ATTR void VKAPI_CALL panvk_DestroySampler(VkDevice _device, VkSampler _sampler, const VkAllocationCallbacks *pAllocator) diff --git a/src/panfrost/vulkan/panvk_private.h b/src/panfrost/vulkan/panvk_private.h index 7c31af846d1..fee8f86fbe5 100644 --- a/src/panfrost/vulkan/panvk_private.h +++ b/src/panfrost/vulkan/panvk_private.h @@ -515,45 +515,6 @@ struct panvk_descriptor_pool { struct panvk_descriptor_set *sets; }; -struct panvk_buffer { - struct vk_buffer vk; - - mali_ptr dev_addr; - - /* TODO: See if we can rework the synchronization logic so we don't need to - * pass BOs around. - */ - struct pan_kmod_bo *bo; - - /* FIXME: Only used for index buffers to do the min/max index retrieval on - * the CPU side. This is all broken anyway and the min/max search should be - * done with a compute shader that also patches the job descriptor - * accordingly (basically an indirect draw). - * - * Make sure this field goes away as soon as we fixed indirect draws. - */ - void *host_ptr; -}; - -static inline mali_ptr -panvk_buffer_gpu_ptr(const struct panvk_buffer *buffer, uint64_t offset) -{ - if (buffer->bo == NULL) - return 0; - - return buffer->dev_addr + offset; -} - -static inline uint64_t -panvk_buffer_range(const struct panvk_buffer *buffer, uint64_t offset, - uint64_t range) -{ - if (buffer->bo == NULL) - return 0; - - return vk_buffer_range(&buffer->vk, offset, range); -} - enum panvk_dynamic_state_bits { PANVK_DYNAMIC_VIEWPORT = 1 << 0, PANVK_DYNAMIC_SCISSOR = 1 << 1, @@ -974,8 +935,6 @@ VK_DEFINE_HANDLE_CASTS(panvk_queue, vk.base, VkQueue, VK_OBJECT_TYPE_QUEUE) VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_cmd_pool, vk.base, VkCommandPool, VK_OBJECT_TYPE_COMMAND_POOL) -VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_buffer, vk.base, VkBuffer, - VK_OBJECT_TYPE_BUFFER) VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_buffer_view, vk.base, VkBufferView, VK_OBJECT_TYPE_BUFFER_VIEW) VK_DEFINE_NONDISP_HANDLE_CASTS(panvk_descriptor_pool, base, VkDescriptorPool, diff --git a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c index 59d329909fe..5aa5295ba88 100644 --- a/src/panfrost/vulkan/panvk_vX_cmd_buffer.c +++ b/src/panfrost/vulkan/panvk_vX_cmd_buffer.c @@ -28,6 +28,7 @@ #include "genxml/gen_macros.h" +#include "panvk_buffer.h" #include "panvk_cs.h" #include "panvk_image.h" #include "panvk_private.h" diff --git a/src/panfrost/vulkan/panvk_vX_cs.c b/src/panfrost/vulkan/panvk_vX_cs.c index 1f87c5a1f01..b12af1214b1 100644 --- a/src/panfrost/vulkan/panvk_vX_cs.c +++ b/src/panfrost/vulkan/panvk_vX_cs.c @@ -34,6 +34,7 @@ #include "pan_pool.h" #include "pan_shader.h" +#include "panvk_buffer.h" #include "panvk_cs.h" #include "panvk_private.h" #include "panvk_varyings.h" diff --git a/src/panfrost/vulkan/panvk_vX_descriptor_set.c b/src/panfrost/vulkan/panvk_vX_descriptor_set.c index ad42ae68b11..4f95ad51f0d 100644 --- a/src/panfrost/vulkan/panvk_vX_descriptor_set.c +++ b/src/panfrost/vulkan/panvk_vX_descriptor_set.c @@ -42,6 +42,7 @@ #include "vk_format.h" #include "vk_util.h" +#include "panvk_buffer.h" #include "panvk_cs.h" #define PANVK_DESCRIPTOR_ALIGN 8 diff --git a/src/panfrost/vulkan/panvk_vX_image.c b/src/panfrost/vulkan/panvk_vX_image.c index cd3610f8c23..822886dd1d9 100644 --- a/src/panfrost/vulkan/panvk_vX_image.c +++ b/src/panfrost/vulkan/panvk_vX_image.c @@ -28,6 +28,7 @@ #include "genxml/gen_macros.h" +#include "panvk_buffer.h" #include "panvk_image.h" #include "panvk_private.h" diff --git a/src/panfrost/vulkan/panvk_vX_meta_copy.c b/src/panfrost/vulkan/panvk_vX_meta_copy.c index 57afb24a060..935389af429 100644 --- a/src/panfrost/vulkan/panvk_vX_meta_copy.c +++ b/src/panfrost/vulkan/panvk_vX_meta_copy.c @@ -28,6 +28,7 @@ #include "pan_props.h" #include "pan_shader.h" +#include "panvk_buffer.h" #include "panvk_image.h" #include "panvk_private.h"