Skip to content

Commit

Permalink
[VK] Clean up command stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
albin-johansson committed Apr 19, 2023
1 parent bde392e commit f633e4d
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 59 deletions.
19 changes: 16 additions & 3 deletions src/core/engine/backends/vulkan_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ namespace {
return builder.build();
}

[[nodiscard]] auto create_graphics_command_pool() -> vk::CommandPoolPtr
{
const auto queue_family_indices =
vk::get_queue_family_indices(vk::get_gpu(), vk::get_surface());
const auto graphics_family_index = queue_family_indices.graphics_family.value();

auto cmd_pool =
vk::create_command_pool(graphics_family_index,
VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
vk::set_graphics_command_pool(cmd_pool.get());

return cmd_pool;
}

} // namespace

VulkanBackend::VulkanBackend()
Expand All @@ -90,8 +104,7 @@ VulkanBackend::VulkanBackend()
mSampler {vk::create_sampler(VK_SAMPLER_ADDRESS_MODE_REPEAT)},
mPipelineCache {vk::create_pipeline_cache()},
mImGuiData {},
mCommandPool {
vk::create_command_pool(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT)}
mGraphicsCommandPool {create_graphics_command_pool()}
{
create_shading_pipeline();
create_frame_data();
Expand Down Expand Up @@ -141,7 +154,7 @@ void VulkanBackend::create_frame_data()
{
for (usize index = 0; index < vk::kMaxFramesInFlight; ++index) {
auto& frame = mFrames.emplace_back();
frame.command_buffer = vk::allocate_command_buffer(mCommandPool.get());
frame.command_buffer = vk::allocate_command_buffer(mGraphicsCommandPool.get());
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/engine/backends/vulkan_backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class VulkanBackend final : public Backend {
vk::SamplerPtr mSampler;
vk::PipelineCachePtr mPipelineCache;
vk::ImGuiData mImGuiData;
vk::CommandPoolPtr mCommandPool;
vk::CommandPoolPtr mGraphicsCommandPool;
vk::DescriptorSetLayoutPtr mShadingDescriptorSetLayout;
vk::PipelineLayoutPtr mShadingPipelineLayout;
vk::PipelinePtr mShadingPipeline;
Expand Down
17 changes: 13 additions & 4 deletions src/core/graphics/vulkan/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,19 @@ auto Buffer::create(const VkBufferUsageFlags usage,
auto staging_buffer = Buffer::staging(data_size, usage);
staging_buffer.set_data(data, data_size);

auto buffer = Buffer::gpu(data_size, usage);
copy_buffer(staging_buffer.get(), buffer.get(), data_size);
auto gpu_buffer = Buffer::gpu(data_size, usage);

return buffer;
execute_immediately(get_graphics_command_pool(), [&](VkCommandBuffer cmd_buffer) {
const VkBufferCopy region {
.srcOffset = 0,
.dstOffset = 0,
.size = data_size,
};

vkCmdCopyBuffer(cmd_buffer, staging_buffer.get(), gpu_buffer.get(), 1, &region);
});

return gpu_buffer;
}

Buffer::~Buffer()
Expand Down Expand Up @@ -163,7 +172,7 @@ auto Buffer::get_allocation_info() -> VmaAllocationInfo

void copy_buffer(VkBuffer src_buffer, VkBuffer dst_buffer, const usize data_size)
{
execute_immediately([=](VkCommandBuffer cmd_buffer) {
execute_immediately(get_graphics_command_pool(), [=](VkCommandBuffer cmd_buffer) {
const VkBufferCopy region {
.srcOffset = 0,
.dstOffset = 0,
Expand Down
32 changes: 17 additions & 15 deletions src/core/graphics/vulkan/cmd/command_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,58 +8,60 @@
namespace glow::vk {
namespace {

[[nodiscard]] auto record_one_time_commands() -> VkCommandBuffer
/// Creates a temporary command buffer.
[[nodiscard]] auto _record_one_time_commands(VkCommandPool cmd_pool) -> VkCommandBuffer
{
VkCommandBuffer cmd_buffer = allocate_command_buffer(get_command_pool());
VkCommandBuffer cmd_buffer = allocate_command_buffer(cmd_pool);
begin_command_buffer(cmd_buffer, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);

return cmd_buffer;
}

void execute_one_time_commands(VkCommandBuffer cmd_buffer)
/// Executes the commands of a temporary command buffer, blocking until the work is done.
void _execute_one_time_commands(VkCommandPool cmd_pool, VkCommandBuffer cmd_buffer)
{
end_command_buffer(cmd_buffer);

VkQueue graphics_queue = get_graphics_queue();
submit_to_queue(graphics_queue, cmd_buffer);
wait_on_queue(graphics_queue);

vkFreeCommandBuffers(get_device(), get_command_pool(), 1, &cmd_buffer);
vkFreeCommandBuffers(get_device(), cmd_pool, 1, &cmd_buffer);
}

} // namespace

void reset_command_buffer(VkCommandBuffer command_buffer)
void reset_command_buffer(VkCommandBuffer cmd_buffer)
{
const VkCommandBufferResetFlags command_buffer_reset_flags = 0;
GLOW_VK_CALL(vkResetCommandBuffer(command_buffer, command_buffer_reset_flags),
const VkCommandBufferResetFlags flags = 0;
GLOW_VK_CALL(vkResetCommandBuffer(cmd_buffer, flags),
"[VK] Could not reset command buffer");
}

void begin_command_buffer(VkCommandBuffer command_buffer,
void begin_command_buffer(VkCommandBuffer cmd_buffer,
const VkCommandBufferUsageFlags flags)
{
const VkCommandBufferBeginInfo command_buffer_begin_info {
const VkCommandBufferBeginInfo begin_info {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.pNext = nullptr,
.flags = flags,
.pInheritanceInfo = nullptr,
};

GLOW_VK_CALL(vkBeginCommandBuffer(command_buffer, &command_buffer_begin_info),
GLOW_VK_CALL(vkBeginCommandBuffer(cmd_buffer, &begin_info),
"[VK] Could not begin command buffer");
}

void end_command_buffer(VkCommandBuffer command_buffer)
void end_command_buffer(VkCommandBuffer cmd_buffer)
{
GLOW_VK_CALL(vkEndCommandBuffer(command_buffer), "[VK] Could not end command buffer");
GLOW_VK_CALL(vkEndCommandBuffer(cmd_buffer), "[VK] Could not end command buffer");
}

void execute_immediately(const UnaryCmdBufferFunc& func)
void execute_immediately(VkCommandPool cmd_pool, const UnaryCmdBufferFunc& func)
{
VkCommandBuffer cmd_buffer = record_one_time_commands();
VkCommandBuffer cmd_buffer = _record_one_time_commands(cmd_pool);
func(cmd_buffer);
execute_one_time_commands(cmd_buffer);
_execute_one_time_commands(cmd_pool, cmd_buffer);
}

} // namespace glow::vk
24 changes: 19 additions & 5 deletions src/core/graphics/vulkan/cmd/command_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,28 @@ namespace glow::vk {

using UnaryCmdBufferFunc = std::function<void(VkCommandBuffer)>;

void reset_command_buffer(VkCommandBuffer command_buffer);

void begin_command_buffer(VkCommandBuffer command_buffer,
/// Resets the state of a command buffer.
///
/// \note The associated command pool must have been created with the
/// `VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT` flag.
///
/// \param cmd_buffer the command buffer that will be reset.
void reset_command_buffer(VkCommandBuffer cmd_buffer);

/// Initializes a command buffer for command recording.
///
/// \param cmd_buffer the command buffer to begin.
/// \param flags optional bitmask of flags.
void begin_command_buffer(VkCommandBuffer cmd_buffer,
VkCommandBufferUsageFlags flags = 0);

void end_command_buffer(VkCommandBuffer command_buffer);
/// Ends the recording of a command buffer.
void end_command_buffer(VkCommandBuffer cmd_buffer);

/// Records a one time command buffer, and executes it (and waits for it to complete).
void execute_immediately(const UnaryCmdBufferFunc& func);
///
/// \param cmd_pool the command pool to allocate the command buffer with.
/// \param func a function object invoked with the temporary command buffer.
void execute_immediately(VkCommandPool cmd_pool, const UnaryCmdBufferFunc& func);

} // namespace glow::vk
27 changes: 11 additions & 16 deletions src/core/graphics/vulkan/cmd/command_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@

#include "common/debug/assert.hpp"
#include "graphics/vulkan/context.hpp"
#include "graphics/vulkan/physical_device.hpp"
#include "graphics/vulkan/util/vk_call.hpp"

namespace glow::vk {
namespace {

void allocate_command_buffers_helper(VkCommandPool pool,
void allocate_command_buffers_helper(VkCommandPool cmd_pool,
const uint32 count,
VkCommandBuffer* out_buffers)
{
Expand All @@ -17,7 +16,7 @@ void allocate_command_buffers_helper(VkCommandPool pool,
const VkCommandBufferAllocateInfo alloc_info {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = nullptr,
.commandPool = pool,
.commandPool = cmd_pool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = count,
};
Expand All @@ -28,49 +27,45 @@ void allocate_command_buffers_helper(VkCommandPool pool,

} // namespace

void CommandPoolDeleter::operator()(VkCommandPool pool) noexcept
void CommandPoolDeleter::operator()(VkCommandPool cmd_pool) noexcept
{
vkDestroyCommandPool(get_device(), pool, nullptr);
vkDestroyCommandPool(get_device(), cmd_pool, nullptr);
}

auto create_command_pool(const VkCommandPoolCreateFlags flags) -> CommandPoolPtr
auto create_command_pool(const uint32 queue_family_index,
const VkCommandPoolCreateFlags flags) -> CommandPoolPtr
{
GLOW_ASSERT(get_surface() != VK_NULL_HANDLE);
GLOW_ASSERT(get_device() != VK_NULL_HANDLE);
GLOW_ASSERT(get_gpu() != VK_NULL_HANDLE);

const auto queue_family_indices = get_queue_family_indices(get_gpu(), get_surface());

const VkCommandPoolCreateInfo create_info {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = nullptr,
.flags = flags,
.queueFamilyIndex = queue_family_indices.graphics_family.value(),
.queueFamilyIndex = queue_family_index,
};

VkCommandPool pool = VK_NULL_HANDLE;
GLOW_VK_CALL(vkCreateCommandPool(get_device(), &create_info, nullptr, &pool),
"[VK] Could not create command pool");

set_command_pool(pool);
return CommandPoolPtr {pool};
}

auto allocate_command_buffers(VkCommandPool command_pool, const uint32 count)
auto allocate_command_buffers(VkCommandPool cmd_pool, const uint32 count)
-> Vector<VkCommandBuffer>
{
Vector<VkCommandBuffer> cmd_buffers;
cmd_buffers.resize(count);

allocate_command_buffers_helper(command_pool, count, cmd_buffers.data());
allocate_command_buffers_helper(cmd_pool, count, cmd_buffers.data());

return cmd_buffers;
}

auto allocate_command_buffer(VkCommandPool command_pool) -> VkCommandBuffer
auto allocate_command_buffer(VkCommandPool cmd_pool) -> VkCommandBuffer
{
VkCommandBuffer cmd_buffer = VK_NULL_HANDLE;
allocate_command_buffers_helper(command_pool, 1, &cmd_buffer);
allocate_command_buffers_helper(cmd_pool, 1, &cmd_buffer);

return cmd_buffer;
}
Expand Down
10 changes: 8 additions & 2 deletions src/core/graphics/vulkan/cmd/command_pool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@ struct CommandPoolDeleter final {

using CommandPoolPtr = Unique<VkCommandPool_T, CommandPoolDeleter>;

/// Creates a command pool for the graphics queue.
[[nodiscard]] auto create_command_pool(VkCommandPoolCreateFlags flags) -> CommandPoolPtr;
/// Creates a command pool for a specific queue.
///
/// \param queue_family_index index of the queue family that derived command buffers will
/// be submitted to.
/// \param flags optional command pool creation flags.
[[nodiscard]] auto create_command_pool(uint32 queue_family_index,
VkCommandPoolCreateFlags flags = 0)
-> CommandPoolPtr;

/// Allocates a specific amount of command buffers from a pool.
[[nodiscard]] auto allocate_command_buffers(VkCommandPool command_pool, uint32 count)
Expand Down
10 changes: 5 additions & 5 deletions src/core/graphics/vulkan/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ inline VkSurfaceKHR gSurface = VK_NULL_HANDLE;
inline VkDevice gDevice = VK_NULL_HANDLE;
inline VkQueue gGraphicsQueue = VK_NULL_HANDLE;
inline VkQueue gPresentationQueue = VK_NULL_HANDLE;
inline VkCommandPool gCommandPool = VK_NULL_HANDLE;
inline VkCommandPool gGraphicsCommandPool = VK_NULL_HANDLE;
inline VmaAllocator gAllocator = VK_NULL_HANDLE;

} // namespace
Expand Down Expand Up @@ -81,9 +81,9 @@ void set_presentation_queue(VkQueue queue) noexcept
gPresentationQueue = queue;
}

void set_command_pool(VkCommandPool pool) noexcept
void set_graphics_command_pool(VkCommandPool pool) noexcept
{
gCommandPool = pool;
gGraphicsCommandPool = pool;
}

void set_allocator(VmaAllocator allocator) noexcept
Expand Down Expand Up @@ -121,9 +121,9 @@ auto get_presentation_queue() noexcept -> VkQueue
return gPresentationQueue;
}

auto get_command_pool() noexcept -> VkCommandPool
auto get_graphics_command_pool() noexcept -> VkCommandPool
{
return gCommandPool;
return gGraphicsCommandPool;
}

auto get_allocator() noexcept -> VmaAllocator
Expand Down
4 changes: 2 additions & 2 deletions src/core/graphics/vulkan/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void set_gpu(VkPhysicalDevice gpu) noexcept;
void set_device(VkDevice device) noexcept;
void set_graphics_queue(VkQueue queue) noexcept;
void set_presentation_queue(VkQueue queue) noexcept;
void set_command_pool(VkCommandPool pool) noexcept;
void set_graphics_command_pool(VkCommandPool pool) noexcept;
void set_allocator(VmaAllocator allocator) noexcept;

[[nodiscard]] auto get_instance() noexcept -> VkInstance;
Expand All @@ -45,7 +45,7 @@ void set_allocator(VmaAllocator allocator) noexcept;
[[nodiscard]] auto get_device() noexcept -> VkDevice;
[[nodiscard]] auto get_graphics_queue() noexcept -> VkQueue;
[[nodiscard]] auto get_presentation_queue() noexcept -> VkQueue;
[[nodiscard]] auto get_command_pool() noexcept -> VkCommandPool;
[[nodiscard]] auto get_graphics_command_pool() noexcept -> VkCommandPool;
[[nodiscard]] auto get_allocator() noexcept -> VmaAllocator;

} // namespace glow::vk
6 changes: 3 additions & 3 deletions src/core/graphics/vulkan/image/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,15 @@ Image::Image(const VkImageType type,

void Image::change_layout(const VkImageLayout new_layout)
{
execute_immediately([=, this](VkCommandBuffer cmd_buffer) {
execute_immediately(get_graphics_command_pool(), [=, this](VkCommandBuffer cmd_buffer) {
transition_image_layout(cmd_buffer, mData.image, mLayout, new_layout, mMipLevels, 0);
mLayout = new_layout;
});
}

void Image::copy_from_buffer(VkBuffer buffer)
{
execute_immediately([=, this](VkCommandBuffer cmd_buffer) {
execute_immediately(get_graphics_command_pool(), [=, this](VkCommandBuffer cmd_buffer) {
const VkBufferImageCopy region {
.bufferOffset = 0,
.bufferRowLength = 0,
Expand All @@ -224,7 +224,7 @@ void Image::generate_mipmaps()
GLOW_ASSERT(mSamples | VK_SAMPLE_COUNT_1_BIT);
GLOW_ASSERT(mLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);

execute_immediately([this](VkCommandBuffer cmd_buffer) {
execute_immediately(get_graphics_command_pool(), [this](VkCommandBuffer cmd_buffer) {
auto mip_width = static_cast<int32>(mExtent.width);
auto mip_height = static_cast<int32>(mExtent.height);

Expand Down
8 changes: 5 additions & 3 deletions src/core/init/dear_imgui_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "common/debug/error.hpp"
#include "graphics/vulkan/cmd/command_buffer.hpp"
#include "graphics/vulkan/context.hpp"

namespace glow {

Expand All @@ -22,9 +23,10 @@ DearImGuiVulkan::~DearImGuiVulkan()

void DearImGuiVulkan::recreate_font_textures()
{
vk::execute_immediately([](VkCommandBuffer cmd_buffer) {
ImGui_ImplVulkan_CreateFontsTexture(cmd_buffer);
});
vk::execute_immediately(vk::get_graphics_command_pool(),
[](VkCommandBuffer cmd_buffer) {
ImGui_ImplVulkan_CreateFontsTexture(cmd_buffer);
});

ImGui_ImplVulkan_DestroyFontUploadObjects();
}
Expand Down

0 comments on commit f633e4d

Please sign in to comment.