venus: add vn_feedback_pool backed by coherent buffer (part 1)
Implemented: - vn_feedback_pool_init - vn_feedback_pool_fini Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org> Reviewed-by: Ryan Neph <ryanneph@google.com> Reviewed-by: Chad Versace <chadversary@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16731>
This commit is contained in:
parent
d578f6c727
commit
27a24caf16
|
@ -56,6 +56,7 @@ libvn_files = files(
|
|||
'vn_descriptor_set.c',
|
||||
'vn_device.c',
|
||||
'vn_device_memory.c',
|
||||
'vn_feedback.c',
|
||||
'vn_icd.c',
|
||||
'vn_image.c',
|
||||
'vn_instance.c',
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#include "vn_feedback.h"
|
||||
|
||||
#include "vn_device.h"
|
||||
#include "vn_physical_device.h"
|
||||
|
||||
/* coherent buffer with bound and mapped memory */
|
||||
struct vn_feedback_buffer {
|
||||
VkBuffer buffer;
|
||||
VkDeviceMemory memory;
|
||||
void *data;
|
||||
|
||||
struct list_head head;
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
vn_get_memory_type_index(const VkPhysicalDeviceMemoryProperties *mem_props,
|
||||
uint32_t mem_type_bits,
|
||||
VkMemoryPropertyFlags required_mem_flags)
|
||||
{
|
||||
u_foreach_bit(mem_type_index, mem_type_bits)
|
||||
{
|
||||
assert(mem_type_index < mem_props->memoryTypeCount);
|
||||
if ((mem_props->memoryTypes[mem_type_index].propertyFlags &
|
||||
required_mem_flags) == required_mem_flags)
|
||||
return mem_type_index;
|
||||
}
|
||||
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
static VkResult
|
||||
vn_feedback_buffer_create(struct vn_device *dev,
|
||||
uint32_t size,
|
||||
const VkAllocationCallbacks *alloc,
|
||||
struct vn_feedback_buffer **out_feedback_buf)
|
||||
{
|
||||
const bool exclusive = dev->queue_family_count == 1;
|
||||
const VkPhysicalDeviceMemoryProperties *mem_props =
|
||||
&dev->physical_device->memory_properties.memoryProperties;
|
||||
VkDevice dev_handle = vn_device_to_handle(dev);
|
||||
struct vn_feedback_buffer *feedback_buf;
|
||||
VkResult result;
|
||||
|
||||
feedback_buf = vk_zalloc(alloc, sizeof(*feedback_buf), VN_DEFAULT_ALIGN,
|
||||
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
||||
if (!feedback_buf)
|
||||
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
|
||||
/* use concurrent to avoid explicit queue family ownership transfer for
|
||||
* device created with queues from multiple queue families
|
||||
*/
|
||||
const VkBufferCreateInfo buf_create_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.size = size,
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT,
|
||||
.sharingMode =
|
||||
exclusive ? VK_SHARING_MODE_EXCLUSIVE : VK_SHARING_MODE_CONCURRENT,
|
||||
/* below favors the current venus protocol */
|
||||
.queueFamilyIndexCount = exclusive ? 0 : dev->queue_family_count,
|
||||
.pQueueFamilyIndices = exclusive ? NULL : dev->queue_families,
|
||||
};
|
||||
result = vn_CreateBuffer(dev_handle, &buf_create_info, alloc,
|
||||
&feedback_buf->buffer);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out_free_feedback_buf;
|
||||
|
||||
struct vn_buffer *buf = vn_buffer_from_handle(feedback_buf->buffer);
|
||||
const VkMemoryRequirements *mem_req =
|
||||
&buf->requirements.memory.memoryRequirements;
|
||||
const uint32_t mem_type_index =
|
||||
vn_get_memory_type_index(mem_props, mem_req->memoryTypeBits,
|
||||
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||
if (mem_type_index >= mem_props->memoryTypeCount) {
|
||||
result = VK_ERROR_INITIALIZATION_FAILED;
|
||||
goto out_destroy_buffer;
|
||||
}
|
||||
|
||||
const VkMemoryAllocateInfo mem_alloc_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.allocationSize = mem_req->size,
|
||||
.memoryTypeIndex = mem_type_index,
|
||||
};
|
||||
result = vn_AllocateMemory(dev_handle, &mem_alloc_info, alloc,
|
||||
&feedback_buf->memory);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out_destroy_buffer;
|
||||
|
||||
const VkBindBufferMemoryInfo bind_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
|
||||
.buffer = feedback_buf->buffer,
|
||||
.memory = feedback_buf->memory,
|
||||
.memoryOffset = 0,
|
||||
};
|
||||
result = vn_BindBufferMemory2(dev_handle, 1, &bind_info);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out_free_memory;
|
||||
|
||||
result = vn_MapMemory(dev_handle, feedback_buf->memory, 0, VK_WHOLE_SIZE,
|
||||
0, &feedback_buf->data);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out_free_memory;
|
||||
|
||||
*out_feedback_buf = feedback_buf;
|
||||
|
||||
return VK_SUCCESS;
|
||||
|
||||
out_free_memory:
|
||||
vn_FreeMemory(dev_handle, feedback_buf->memory, alloc);
|
||||
|
||||
out_destroy_buffer:
|
||||
vn_DestroyBuffer(dev_handle, feedback_buf->buffer, alloc);
|
||||
|
||||
out_free_feedback_buf:
|
||||
vk_free(alloc, feedback_buf);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
vn_feedback_buffer_destroy(struct vn_device *dev,
|
||||
struct vn_feedback_buffer *feedback_buf,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
VkDevice dev_handle = vn_device_to_handle(dev);
|
||||
|
||||
vn_UnmapMemory(dev_handle, feedback_buf->memory);
|
||||
vn_FreeMemory(dev_handle, feedback_buf->memory, alloc);
|
||||
vn_DestroyBuffer(dev_handle, feedback_buf->buffer, alloc);
|
||||
vk_free(alloc, feedback_buf);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
vn_feedback_pool_grow(struct vn_feedback_pool *pool)
|
||||
{
|
||||
VN_TRACE_FUNC();
|
||||
struct vn_feedback_buffer *feedback_buf = NULL;
|
||||
VkResult result;
|
||||
|
||||
result = vn_feedback_buffer_create(pool->device, pool->size, pool->alloc,
|
||||
&feedback_buf);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
pool->used = 0;
|
||||
|
||||
list_add(&feedback_buf->head, &pool->feedback_buffers);
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_feedback_pool_init(struct vn_device *dev,
|
||||
struct vn_feedback_pool *pool,
|
||||
uint32_t size,
|
||||
const VkAllocationCallbacks *alloc)
|
||||
{
|
||||
pool->device = dev;
|
||||
pool->alloc = alloc;
|
||||
pool->size = size;
|
||||
pool->used = size;
|
||||
list_inithead(&pool->feedback_buffers);
|
||||
|
||||
return vn_feedback_pool_grow(pool);
|
||||
}
|
||||
|
||||
void
|
||||
vn_feedback_pool_fini(struct vn_feedback_pool *pool)
|
||||
{
|
||||
list_for_each_entry_safe(struct vn_feedback_buffer, feedback_buf,
|
||||
&pool->feedback_buffers, head)
|
||||
vn_feedback_buffer_destroy(pool->device, feedback_buf, pool->alloc);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright 2022 Google LLC
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
#ifndef VN_FEEDBACK_H
|
||||
#define VN_FEEDBACK_H
|
||||
|
||||
#include "vn_common.h"
|
||||
|
||||
struct vn_feedback_pool {
|
||||
struct vn_device *device;
|
||||
const VkAllocationCallbacks *alloc;
|
||||
|
||||
/* size in bytes of the feedback buffer */
|
||||
uint32_t size;
|
||||
/* size in bytes used of the active feedback buffer */
|
||||
uint32_t used;
|
||||
|
||||
/* first entry is the active feedback buffer */
|
||||
struct list_head feedback_buffers;
|
||||
};
|
||||
|
||||
VkResult
|
||||
vn_feedback_pool_init(struct vn_device *dev,
|
||||
struct vn_feedback_pool *pool,
|
||||
uint32_t size,
|
||||
const VkAllocationCallbacks *alloc);
|
||||
|
||||
void
|
||||
vn_feedback_pool_fini(struct vn_feedback_pool *pool);
|
||||
|
||||
#endif /* VN_FEEDBACK_H */
|
Loading…
Reference in New Issue