Skip to content

Commit 53f83a6

Browse files
authored
Merge pull request #18 from CapsCollective/feature/command-buffer
Added Command Buffer wrapper class
2 parents 8ba6f93 + bb8323d commit 53f83a6

20 files changed

+327
-197
lines changed

engine/render/renderer/Renderer.cpp

Lines changed: 20 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
namespace Siege
1616
{
1717
Renderer* Renderer::instance {nullptr};
18-
Utils::MHArray<VkCommandBuffer> Renderer::commandBuffers;
18+
Vulkan::CommandBuffer Renderer::commandBuffers;
19+
uint32_t Renderer::currentFrameIndex = 0;
1920

2021
Renderer::Renderer(Window& window) : window {window}
2122
{
@@ -37,7 +38,7 @@ Renderer::Renderer(Window& window) : window {window}
3738
Renderer3D::Initialise();
3839
Renderer2D::Initialise();
3940

40-
CreateCommandBuffers();
41+
commandBuffers = Vulkan::CommandBuffer(Vulkan::Swapchain::MAX_FRAMES_IN_FLIGHT);
4142
}
4243

4344
Renderer::~Renderer()
@@ -47,25 +48,9 @@ Renderer::~Renderer()
4748
Renderer3D::DestroyRenderer3D();
4849
}
4950

50-
void Renderer::CreateCommandBuffers()
51-
{
52-
commandBuffers = Utils::MHArray<VkCommandBuffer>(Vulkan::Swapchain::MAX_FRAMES_IN_FLIGHT);
53-
54-
VkCommandBufferAllocateInfo allocInfo {};
55-
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
56-
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
57-
allocInfo.commandPool = Vulkan::Context::GetCurrentDevice()->GetCommandPool();
58-
allocInfo.commandBufferCount = static_cast<uint32_t>(commandBuffers.Size());
59-
60-
CC_ASSERT(vkAllocateCommandBuffers(Vulkan::Context::GetVkLogicalDevice(),
61-
&allocInfo,
62-
OUT commandBuffers.Data()) == VK_SUCCESS,
63-
"Failed to allocate command buffer");
64-
}
65-
6651
void Renderer::DrawFrame()
6752
{
68-
auto commandBuffer = GetCurrentCommandBuffer();
53+
auto commandBuffer = commandBuffers.GetActiveCommandBuffer();
6954

7055
Renderer2D::GlobalData global2DData = {projection};
7156

@@ -101,7 +86,7 @@ void Renderer::RecreateSwapChain()
10186

10287
bool Renderer::StartFrame()
10388
{
104-
CC_ASSERT(!isFrameStarted, "Can't start a frame when a frame is already in progress!");
89+
CC_ASSERT(!isFrameStarted, "Can't start a frame when a frame is already in progress!")
10590

10691
auto& swapchain = context.GetSwapchain();
10792

@@ -114,19 +99,13 @@ bool Renderer::StartFrame()
11499
}
115100

116101
CC_ASSERT(result == Vulkan::Utils::SUCCESS || result == Vulkan::Utils::SUBOPTIMAL,
117-
"Failed to acquire swapchain image!");
102+
"Failed to acquire swapchain image!")
118103

119104
isFrameStarted = true;
120105

121-
VkCommandBuffer commandBuffer = GetCurrentCommandBuffer();
122-
123-
VkCommandBufferBeginInfo beginInfo {};
124-
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
125-
126-
CC_ASSERT(vkBeginCommandBuffer(OUT commandBuffer, &beginInfo) == VK_SUCCESS,
127-
"Failed to begin recording command buffer");
106+
commandBuffers.Begin(currentFrameIndex);
128107

129-
BeginSwapChainRenderPass(commandBuffer);
108+
BeginSwapChainRenderPass();
130109

131110
return true;
132111
}
@@ -139,14 +118,13 @@ void Renderer::EndFrame()
139118

140119
DrawFrame();
141120

142-
VkCommandBuffer commandBuffer = GetCurrentCommandBuffer();
121+
EndSwapChainRenderPass();
143122

144-
EndSwapChainRenderPass(commandBuffer);
123+
commandBuffers.End();
145124

146-
CC_ASSERT(vkEndCommandBuffer(OUT commandBuffer) == VK_SUCCESS,
147-
"Failed to record command buffer!");
125+
commandBuffers.SetActiveBufferIndex(currentFrameIndex);
148126

149-
auto result = swapchain.SubmitCommandBuffers(&commandBuffer, &currentImageIndex);
127+
auto result = swapchain.SubmitCommandBuffers(commandBuffers, currentImageIndex);
150128

151129
if (result == Vulkan::Utils::ERROR_RESIZED || window.WasResized())
152130
{
@@ -161,17 +139,15 @@ void Renderer::EndFrame()
161139
Renderer2D::Flush();
162140
}
163141

164-
void Renderer::BeginSwapChainRenderPass(VkCommandBuffer commandBuffer)
142+
void Renderer::BeginSwapChainRenderPass()
165143
{
166144
auto& swapchain = context.GetSwapchain();
167145

168-
CC_ASSERT(isFrameStarted, "Can't start render pass while the frame hasn't started!");
169-
CC_ASSERT(commandBuffer == GetCurrentCommandBuffer(),
170-
"Can't begin a render pass on a command buffer from another frame!");
146+
CC_ASSERT(isFrameStarted, "Can't start render pass while the frame hasn't started!")
171147

172148
auto swapExtent = swapchain.GetExtent();
173149

174-
swapchain.BeginRenderPass(OUT commandBuffer, currentImageIndex, {{clearValue}, {{{1.f, 0.f}}}});
150+
swapchain.BeginRenderPass(commandBuffers, currentImageIndex, {{clearValue}, {{{1.f, 0.f}}}});
175151

176152
VkViewport viewport {};
177153
viewport.x = 0.0f;
@@ -182,18 +158,16 @@ void Renderer::BeginSwapChainRenderPass(VkCommandBuffer commandBuffer)
182158
viewport.maxDepth = 1.0f;
183159
VkRect2D scissor {{0, 0}, {swapExtent.width, swapExtent.height}};
184160

185-
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
186-
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
161+
vkCmdSetViewport(commandBuffers.GetActiveCommandBuffer(), 0, 1, &viewport);
162+
vkCmdSetScissor(commandBuffers.GetActiveCommandBuffer(), 0, 1, &scissor);
187163
}
188164

189-
void Renderer::EndSwapChainRenderPass(VkCommandBuffer commandBuffer)
165+
void Renderer::EndSwapChainRenderPass()
190166
{
191167
auto& swapchain = context.GetSwapchain();
192168

193-
CC_ASSERT(isFrameStarted, "Can't end render pass while the frame hasn't started!");
194-
CC_ASSERT(commandBuffer == GetCurrentCommandBuffer(),
195-
"Can't end a render pass on a command buffer from another frame!");
169+
CC_ASSERT(isFrameStarted, "Can't end render pass while the frame hasn't started!")
196170

197-
swapchain.EndRenderPass(commandBuffer);
171+
swapchain.EndRenderPass(commandBuffers);
198172
}
199173
} // namespace Siege

engine/render/renderer/Renderer.h

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "material/Material.h"
1717
#include "model/Model.h"
1818
#include "pipeline/Pipeline.h"
19+
#include "render/renderer/platform/vulkan/CommandBuffer.h"
1920
#include "render/renderer/platform/vulkan/Context.h"
2021
#include "render/window/Window.h"
2122
#include "renderer/Renderer2D.h"
@@ -31,12 +32,6 @@ class Renderer
3132

3233
~Renderer();
3334

34-
int GetCurrentFrameIndex() const
35-
{
36-
CC_ASSERT(!isFrameStarted, "Can't get frame index when frame is not in progress!");
37-
return currentFrameIndex;
38-
}
39-
4035
float GetAspectRatio() const
4136
{
4237
return static_cast<float>(window.GetWidth()) / static_cast<float>(window.GetHeight());
@@ -47,12 +42,6 @@ class Renderer
4742
projection = {projectionMat, viewMat};
4843
}
4944

50-
VkCommandBuffer GetCurrentCommandBuffer() const
51-
{
52-
CC_ASSERT(isFrameStarted, "Can't get command buffer when frame is not in progress!")
53-
return commandBuffers[currentFrameIndex];
54-
}
55-
5645
bool StartFrame();
5746
void EndFrame();
5847

@@ -79,27 +68,25 @@ class Renderer
7968
private:
8069

8170
static Renderer* instance;
82-
static Utils::MHArray<VkCommandBuffer> commandBuffers;
71+
static Vulkan::CommandBuffer commandBuffers;
72+
static uint32_t currentFrameIndex;
8373

8474
Vulkan::Context context;
8575

8676
// Make this adjustable in the window, not the renderer.
8777
VkClearColorValue clearValue {{0.96f, 0.96f, 0.96f, 1.f}};
8878

89-
void CreateCommandBuffers();
90-
9179
void RecreateSwapChain();
9280

93-
void BeginSwapChainRenderPass(VkCommandBuffer commandBuffer);
94-
void EndSwapChainRenderPass(VkCommandBuffer commandBuffer);
81+
void BeginSwapChainRenderPass();
82+
void EndSwapChainRenderPass();
9583

9684
void DrawFrame();
9785

9886
Window& window;
9987

10088
uint32_t currentImageIndex;
10189
bool isFrameStarted {false};
102-
int currentFrameIndex {0};
10390

10491
CameraData projection;
10592
};

engine/render/renderer/pass/RenderPass.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ void RenderPass::DestroyRenderPass()
3131
}
3232

3333
void RenderPass::Begin(VkRenderPass renderPass,
34-
VkCommandBuffer commandBuffer,
34+
Vulkan::CommandBuffer& commandBuffer,
3535
VkFramebuffer frameBuffer,
3636
VkOffset2D offset,
3737
VkExtent2D extent,
@@ -49,12 +49,14 @@ void RenderPass::Begin(VkRenderPass renderPass,
4949
renderPassInfo.clearValueCount = clearValueCount;
5050
renderPassInfo.pClearValues = clearValues;
5151

52-
vkCmdBeginRenderPass(OUT commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
52+
vkCmdBeginRenderPass(OUT commandBuffer.GetActiveCommandBuffer(),
53+
&renderPassInfo,
54+
VK_SUBPASS_CONTENTS_INLINE);
5355
}
5456

55-
void RenderPass::End(VkCommandBuffer commandBuffer)
57+
void RenderPass::End(Vulkan::CommandBuffer& commandBuffer)
5658
{
57-
vkCmdEndRenderPass(OUT commandBuffer);
59+
vkCmdEndRenderPass(OUT commandBuffer.GetActiveCommandBuffer());
5860
}
5961

6062
RenderPass::RenderPass() = default;

engine/render/renderer/pass/RenderPass.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define SIEGE_ENGINE_RENDER_PASS_H
1111

1212
#include "../Core.h"
13+
#include "render/renderer/platform/vulkan/CommandBuffer.h"
1314
#include "utils/Attachments.h"
1415

1516
namespace Siege
@@ -191,7 +192,7 @@ class RenderPass
191192
* @param clearValueCount The number of clear values provided
192193
*/
193194
static void Begin(VkRenderPass renderPass,
194-
VkCommandBuffer commandBuffer,
195+
Vulkan::CommandBuffer& commandBuffer,
195196
VkFramebuffer frameBuffer,
196197
VkOffset2D offset,
197198
VkExtent2D extent,
@@ -204,7 +205,7 @@ class RenderPass
204205
*
205206
* @param commandBuffer The command buffer currently being recorded to
206207
*/
207-
static void End(VkCommandBuffer commandBuffer);
208+
static void End(Vulkan::CommandBuffer& commandBuffer);
208209

209210
inline RenderPass& operator=(RenderPass&& other) noexcept
210211
{
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//
2+
// Copyright (c) 2022 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr)
3+
//
4+
// This code is released under an unmodified zlib license.
5+
// For conditions of distribution and use, please see:
6+
// https://opensource.org/licenses/Zlib
7+
//
8+
9+
#include "CommandBuffer.h"
10+
11+
#include "Context.h"
12+
#include "utils/CommandBuffer.h"
13+
#include "utils/SubmitCommands.h"
14+
15+
namespace Siege::Vulkan
16+
{
17+
CommandBuffer::CommandBuffer(uint32_t count)
18+
{
19+
auto device = Context::GetVkLogicalDevice();
20+
auto pool = Context::GetCurrentDevice()->GetCommandPool();
21+
22+
commandBuffers = Utils::CommandBuffer::AllocateCommandBuffers(device, pool, count);
23+
}
24+
25+
void CommandBuffer::Begin(int32_t index)
26+
{
27+
auto commandBuffer = commandBuffers[index];
28+
29+
Utils::CommandBuffer::BeginSingleTimeCommand(commandBuffer);
30+
31+
activeCommandBuffer = commandBuffer;
32+
}
33+
34+
void CommandBuffer::End()
35+
{
36+
Utils::CommandBuffer::EndCommandBuffer(activeCommandBuffer);
37+
38+
activeCommandBuffer = nullptr;
39+
}
40+
41+
void CommandBuffer::Submit(const size_t index)
42+
{
43+
Vulkan::Fence fence(1, Fence::FENCE_EMPTY);
44+
45+
Utils::SubmitGraphicsCommand()
46+
.ToQueue(Vulkan::Context::GetCurrentDevice()->GetGraphicsQueue())
47+
.WithCommandBuffers({commandBuffers[index]})
48+
.Submit(fence.Get());
49+
50+
fence.Wait();
51+
}
52+
53+
void CommandBuffer::Swap(CommandBuffer& other)
54+
{
55+
auto tmpCmdBuffers = std::move(commandBuffers);
56+
auto tmpActiveCmdBuffer = activeCommandBuffer;
57+
auto tmpCurrentActiveBufferIndex = currentActiveBufferIndex;
58+
59+
commandBuffers = std::move(other.commandBuffers);
60+
activeCommandBuffer = other.activeCommandBuffer;
61+
currentActiveBufferIndex = other.currentActiveBufferIndex;
62+
63+
other.commandBuffers = std::move(tmpCmdBuffers);
64+
other.activeCommandBuffer = tmpActiveCmdBuffer;
65+
other.currentActiveBufferIndex = tmpCurrentActiveBufferIndex;
66+
}
67+
} // namespace Siege::Vulkan

0 commit comments

Comments
 (0)