mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-19 21:28:50 +00:00
aux/vk: Add many more helper functions
This commit is contained in:
parent
5554b0fa00
commit
e8b0ab3b35
|
@ -184,11 +184,13 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/u_git_tag.c.in" "${CMAKE_CURREN
|
|||
list(APPEND UTIL_SOURCE_FILES "${CMAKE_CURRENT_BINARY_DIR}/u_git_tag.c")
|
||||
|
||||
set(VK_SOURCE_FILES
|
||||
vk/vk_command_buffer.c
|
||||
vk/vk_documentation.h
|
||||
vk/vk_helpers.c
|
||||
vk/vk_helpers.h
|
||||
vk/vk_image_allocator.c
|
||||
vk/vk_image_allocator.h
|
||||
vk/vk_state_creators.c
|
||||
)
|
||||
|
||||
# Common includes
|
||||
|
|
|
@ -271,11 +271,13 @@ aux_vive = declare_dependency(
|
|||
lib_aux_vk = static_library(
|
||||
'aux_vk',
|
||||
files(
|
||||
'vk/vk_command_buffer.c',
|
||||
'vk/vk_documentation.h',
|
||||
'vk/vk_helpers.h',
|
||||
'vk/vk_helpers.c',
|
||||
'vk/vk_image_allocator.h',
|
||||
'vk/vk_image_allocator.c',
|
||||
'vk/vk_state_creators.c',
|
||||
),
|
||||
include_directories: [
|
||||
xrt_include,
|
||||
|
|
96
src/xrt/auxiliary/vk/vk_command_buffer.c
Normal file
96
src/xrt/auxiliary/vk/vk_command_buffer.c
Normal file
|
@ -0,0 +1,96 @@
|
|||
// Copyright 2019-2021, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Vulkan command buffer helpers.
|
||||
*
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @ingroup aux_vk
|
||||
*/
|
||||
|
||||
#include "vk/vk_helpers.h"
|
||||
|
||||
|
||||
VkResult
|
||||
vk_create_command_buffer(struct vk_bundle *vk, VkCommandBuffer *out_command_buffer)
|
||||
{
|
||||
VkResult ret;
|
||||
|
||||
VkCommandBufferAllocateInfo cmd_buffer_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.commandPool = vk->cmd_pool,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandBufferCount = 1,
|
||||
};
|
||||
|
||||
VkCommandBuffer cmd = VK_NULL_HANDLE;
|
||||
|
||||
os_mutex_lock(&vk->cmd_pool_mutex);
|
||||
|
||||
ret = vk->vkAllocateCommandBuffers( //
|
||||
vk->device, // device
|
||||
&cmd_buffer_info, // pAllocateInfo
|
||||
&cmd); // pCommandBuffers
|
||||
|
||||
os_mutex_unlock(&vk->cmd_pool_mutex);
|
||||
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "vkCreateFramebuffer failed: %s", vk_result_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
*out_command_buffer = cmd;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
vk_destroy_command_buffer(struct vk_bundle *vk, VkCommandBuffer command_buffer)
|
||||
{
|
||||
os_mutex_lock(&vk->cmd_pool_mutex);
|
||||
|
||||
vk->vkFreeCommandBuffers( //
|
||||
vk->device, // device
|
||||
vk->cmd_pool, // commandPool
|
||||
1, // commandBufferCount
|
||||
&command_buffer); // pCommandBuffers
|
||||
|
||||
os_mutex_unlock(&vk->cmd_pool_mutex);
|
||||
}
|
||||
|
||||
VkResult
|
||||
vk_begin_command_buffer(struct vk_bundle *vk, VkCommandBuffer command_buffer)
|
||||
{
|
||||
VkResult ret;
|
||||
|
||||
VkCommandBufferBeginInfo command_buffer_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
};
|
||||
|
||||
ret = vk->vkBeginCommandBuffer( //
|
||||
command_buffer, // commandBuffer
|
||||
&command_buffer_info); // pBeginInfo
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "vkBeginCommandBuffer failed: %s", vk_result_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vk_end_command_buffer(struct vk_bundle *vk, VkCommandBuffer command_buffer)
|
||||
{
|
||||
VkResult ret;
|
||||
|
||||
// End the command buffer.
|
||||
ret = vk->vkEndCommandBuffer( //
|
||||
command_buffer); // commandBuffer
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "vkEndCommandBuffer failed: %s", vk_result_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
|
@ -669,6 +669,121 @@ vk_update_buffer(struct vk_bundle *vk, float *buffer, size_t buffer_size, VkDevi
|
|||
VkResult
|
||||
vk_locked_submit(struct vk_bundle *vk, VkQueue queue, uint32_t count, const VkSubmitInfo *infos, VkFence fence);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* State creation helpers, in the vk_state_creators.c file.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Arguments to @ref vk_create_descriptor_pool function.
|
||||
*/
|
||||
struct vk_descriptor_pool_info
|
||||
{
|
||||
uint32_t uniform_per_descriptor_count; //!< VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
|
||||
uint32_t sampler_per_descriptor_count; //!< VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
|
||||
uint32_t storage_image_per_descriptor_count; //!< VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
|
||||
uint32_t storage_buffer_per_descriptor_count; //!< VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
|
||||
|
||||
//! The max count of created descriptors.
|
||||
uint32_t descriptor_count;
|
||||
|
||||
//! Are descriptors freeable, or must vkResetDescriptorPool be used.
|
||||
bool freeable;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Creates a descriptor pool, made for a single layout.
|
||||
*
|
||||
* Does error logging.
|
||||
*/
|
||||
VkResult
|
||||
vk_create_descriptor_pool(struct vk_bundle *vk,
|
||||
const struct vk_descriptor_pool_info *info,
|
||||
VkDescriptorPool *out_descriptor_pool);
|
||||
|
||||
/*!
|
||||
* Creates a descriptor set.
|
||||
*
|
||||
* Does error logging.
|
||||
*/
|
||||
VkResult
|
||||
vk_create_descriptor_set(struct vk_bundle *vk,
|
||||
VkDescriptorPool descriptor_pool,
|
||||
VkDescriptorSetLayout descriptor_layout,
|
||||
VkDescriptorSet *out_descriptor_set);
|
||||
|
||||
/*!
|
||||
* Creates a pipeline layout from a single descriptor set layout.
|
||||
*
|
||||
* Does error logging.
|
||||
*/
|
||||
VkResult
|
||||
vk_create_pipeline_layout(struct vk_bundle *vk,
|
||||
VkDescriptorSetLayout descriptor_set_layout,
|
||||
VkPipelineLayout *out_pipeline_layout);
|
||||
|
||||
/*!
|
||||
* Creates a pipeline cache.
|
||||
*
|
||||
* Does error logging.
|
||||
*/
|
||||
VkResult
|
||||
vk_create_pipeline_cache(struct vk_bundle *vk, VkPipelineCache *out_pipeline_cache);
|
||||
|
||||
/*!
|
||||
* Creates a compute pipeline, assumes entry function is called 'main'.
|
||||
*
|
||||
* Does error logging.
|
||||
*/
|
||||
VkResult
|
||||
vk_create_compute_pipeline(struct vk_bundle *vk,
|
||||
VkPipelineCache pipeline_cache,
|
||||
VkShaderModule shader,
|
||||
VkPipelineLayout pipeline_layout,
|
||||
VkPipeline *out_compute_pipeline);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Command buffer helpers, in the vk_command_buffer.c file.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Creates a new command buffer using the bundle's pool, takes the cmd_pool_mutex.
|
||||
*
|
||||
* Does error logging.
|
||||
*/
|
||||
VkResult
|
||||
vk_create_command_buffer(struct vk_bundle *vk, VkCommandBuffer *out_cmd);
|
||||
|
||||
/*!
|
||||
* Destroys a command buffer, takes the cmd_pool_mutex.
|
||||
*
|
||||
* Does error logging.
|
||||
*/
|
||||
void
|
||||
vk_destroy_command_buffer(struct vk_bundle *vk, VkCommandBuffer command_buffer);
|
||||
|
||||
/*!
|
||||
* Issues the vkBeginCommandBuffer function on the command buffer.
|
||||
*
|
||||
* Does error logging.
|
||||
*/
|
||||
VkResult
|
||||
vk_begin_command_buffer(struct vk_bundle *vk, VkCommandBuffer command_buffer);
|
||||
|
||||
/*!
|
||||
* Issues the vkEndCommandBuffer function on the command buffer.
|
||||
*
|
||||
* Does error logging.
|
||||
*/
|
||||
VkResult
|
||||
vk_end_command_buffer(struct vk_bundle *vk, VkCommandBuffer command_buffer);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
212
src/xrt/auxiliary/vk/vk_state_creators.c
Normal file
212
src/xrt/auxiliary/vk/vk_state_creators.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
// Copyright 2019-2021, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Vulkan state creators helpers.
|
||||
*
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @author Lubosz Sarnecki <lubosz.sarnecki@collabora.com>
|
||||
* @ingroup aux_vk
|
||||
*/
|
||||
|
||||
#include "vk/vk_helpers.h"
|
||||
|
||||
|
||||
VkResult
|
||||
vk_create_descriptor_pool(struct vk_bundle *vk,
|
||||
const struct vk_descriptor_pool_info *info,
|
||||
VkDescriptorPool *out_descriptor_pool)
|
||||
{
|
||||
VkResult ret;
|
||||
|
||||
uint32_t pool_count = 0;
|
||||
VkDescriptorPoolSize pool_sizes[4] = {0};
|
||||
|
||||
const uint32_t descriptor_count = info->descriptor_count;
|
||||
const uint32_t uniform_count = info->uniform_per_descriptor_count * descriptor_count;
|
||||
const uint32_t sampler_count = info->sampler_per_descriptor_count * descriptor_count;
|
||||
const uint32_t storage_image_count = info->storage_image_per_descriptor_count * descriptor_count;
|
||||
const uint32_t storage_buffer_count = info->storage_buffer_per_descriptor_count * descriptor_count;
|
||||
|
||||
if (uniform_count > 0) {
|
||||
pool_sizes[pool_count].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||
pool_sizes[pool_count].descriptorCount = uniform_count;
|
||||
pool_count++;
|
||||
}
|
||||
|
||||
if (sampler_count > 0) {
|
||||
pool_sizes[pool_count].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
pool_sizes[pool_count].descriptorCount = sampler_count;
|
||||
pool_count++;
|
||||
}
|
||||
|
||||
if (storage_image_count > 0) {
|
||||
pool_sizes[pool_count].type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
|
||||
pool_sizes[pool_count].descriptorCount = storage_image_count;
|
||||
pool_count++;
|
||||
}
|
||||
|
||||
if (storage_buffer_count > 0) {
|
||||
pool_sizes[pool_count].type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
|
||||
pool_sizes[pool_count].descriptorCount = storage_buffer_count;
|
||||
pool_count++;
|
||||
}
|
||||
|
||||
assert(pool_count > 0 && pool_count <= ARRAY_SIZE(pool_sizes));
|
||||
|
||||
VkDescriptorPoolCreateFlags flags = 0;
|
||||
|
||||
if (info->freeable) {
|
||||
flags |= VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||
}
|
||||
|
||||
VkDescriptorPoolCreateInfo descriptor_pool_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
|
||||
.flags = flags,
|
||||
.maxSets = descriptor_count,
|
||||
.poolSizeCount = pool_count,
|
||||
.pPoolSizes = pool_sizes,
|
||||
};
|
||||
|
||||
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
|
||||
ret = vk->vkCreateDescriptorPool( //
|
||||
vk->device, // device
|
||||
&descriptor_pool_info, // pCreateInfo
|
||||
NULL, // pAllocator
|
||||
&descriptor_pool); // pDescriptorPool
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "vkCreateRenderPass failed: %s", vk_result_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
*out_descriptor_pool = descriptor_pool;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vk_create_descriptor_set(struct vk_bundle *vk,
|
||||
VkDescriptorPool descriptor_pool,
|
||||
VkDescriptorSetLayout descriptor_layout,
|
||||
VkDescriptorSet *out_descriptor_set)
|
||||
{
|
||||
VkResult ret;
|
||||
|
||||
VkDescriptorSetAllocateInfo alloc_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||
.descriptorPool = descriptor_pool,
|
||||
.descriptorSetCount = 1,
|
||||
.pSetLayouts = &descriptor_layout,
|
||||
};
|
||||
|
||||
VkDescriptorSet descriptor_set = VK_NULL_HANDLE;
|
||||
ret = vk->vkAllocateDescriptorSets( //
|
||||
vk->device, // device
|
||||
&alloc_info, // pAllocateInfo
|
||||
&descriptor_set); // pDescriptorSets
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_DEBUG(vk, "vkAllocateDescriptorSets failed: %s", vk_result_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
*out_descriptor_set = descriptor_set;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vk_create_pipeline_layout(struct vk_bundle *vk,
|
||||
VkDescriptorSetLayout descriptor_set_layout,
|
||||
VkPipelineLayout *out_pipeline_layout)
|
||||
{
|
||||
VkResult ret;
|
||||
|
||||
VkPipelineLayoutCreateInfo pipeline_layout_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
|
||||
.setLayoutCount = 1,
|
||||
.pSetLayouts = &descriptor_set_layout,
|
||||
};
|
||||
|
||||
VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
|
||||
ret = vk->vkCreatePipelineLayout( //
|
||||
vk->device, // device
|
||||
&pipeline_layout_info, // pCreateInfo
|
||||
NULL, // pAllocator
|
||||
&pipeline_layout); // pPipelineLayout
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "vkCreatePipelineLayout failed: %s", vk_result_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
*out_pipeline_layout = pipeline_layout;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vk_create_pipeline_cache(struct vk_bundle *vk, VkPipelineCache *out_pipeline_cache)
|
||||
{
|
||||
VkResult ret;
|
||||
|
||||
VkPipelineCacheCreateInfo pipeline_cache_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
|
||||
};
|
||||
|
||||
VkPipelineCache pipeline_cache;
|
||||
ret = vk->vkCreatePipelineCache( //
|
||||
vk->device, // device
|
||||
&pipeline_cache_info, // pCreateInfo
|
||||
NULL, // pAllocator
|
||||
&pipeline_cache); // pPipelineCache
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_ERROR(vk, "vkCreatePipelineCache failed: %s", vk_result_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
*out_pipeline_cache = pipeline_cache;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vk_create_compute_pipeline(struct vk_bundle *vk,
|
||||
VkPipelineCache pipeline_cache,
|
||||
VkShaderModule shader,
|
||||
VkPipelineLayout pipeline_layout,
|
||||
VkPipeline *out_compute_pipeline)
|
||||
{
|
||||
VkResult ret;
|
||||
|
||||
VkPipelineShaderStageCreateInfo shader_stage_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
|
||||
.module = shader,
|
||||
.pName = "main",
|
||||
};
|
||||
|
||||
VkComputePipelineCreateInfo pipeline_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.flags = 0,
|
||||
.stage = shader_stage_info,
|
||||
.layout = pipeline_layout,
|
||||
};
|
||||
|
||||
VkPipeline pipeline = VK_NULL_HANDLE;
|
||||
ret = vk->vkCreateComputePipelines( //
|
||||
vk->device, // device
|
||||
pipeline_cache, // pipelineCache
|
||||
1, // createInfoCount
|
||||
&pipeline_info, // pCreateInfos
|
||||
NULL, // pAllocator
|
||||
&pipeline); // pPipelines
|
||||
if (ret != VK_SUCCESS) {
|
||||
VK_DEBUG(vk, "vkCreateComputePipelines failed: %s", vk_result_string(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
*out_compute_pipeline = pipeline;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
Loading…
Reference in a new issue