1 #include "GSH_VulkanFrameCommandBuffer.h"
2 #include "vulkan/StructDefs.h"
3
4 using namespace GSH_Vulkan;
5
CFrameCommandBuffer(const ContextPtr & context)6 CFrameCommandBuffer::CFrameCommandBuffer(const ContextPtr& context)
7 : m_context(context)
8 {
9 auto result = VK_SUCCESS;
10
11 for(auto& frame : m_frames)
12 {
13 frame.commandBuffer = m_context->commandBufferPool.AllocateBuffer();
14
15 {
16 auto fenceCreateInfo = Framework::Vulkan::FenceCreateInfo();
17 fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
18 result = m_context->device.vkCreateFence(m_context->device, &fenceCreateInfo, nullptr, &frame.execCompleteFence);
19 CHECKVULKANERROR(result);
20 }
21 }
22 }
23
~CFrameCommandBuffer()24 CFrameCommandBuffer::~CFrameCommandBuffer()
25 {
26 for(auto& frame : m_frames)
27 {
28 m_context->device.vkDestroyFence(m_context->device, frame.execCompleteFence, nullptr);
29 }
30 }
31
RegisterWriter(IFrameCommandBufferWriter * writer)32 void CFrameCommandBuffer::RegisterWriter(IFrameCommandBufferWriter* writer)
33 {
34 m_writers.push_back(writer);
35 }
36
BeginFrame()37 void CFrameCommandBuffer::BeginFrame()
38 {
39 const auto& frame = m_frames[m_currentFrame];
40
41 auto result = VK_SUCCESS;
42
43 result = m_context->device.vkWaitForFences(m_context->device, 1, &frame.execCompleteFence, VK_TRUE, UINT64_MAX);
44 CHECKVULKANERROR(result);
45
46 result = m_context->device.vkResetFences(m_context->device, 1, &frame.execCompleteFence);
47 CHECKVULKANERROR(result);
48
49 result = m_context->device.vkResetCommandBuffer(frame.commandBuffer, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
50 CHECKVULKANERROR(result);
51
52 auto commandBufferBeginInfo = Framework::Vulkan::CommandBufferBeginInfo();
53 commandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
54 result = m_context->device.vkBeginCommandBuffer(frame.commandBuffer, &commandBufferBeginInfo);
55 CHECKVULKANERROR(result);
56 }
57
EndFrame()58 void CFrameCommandBuffer::EndFrame()
59 {
60 for(const auto& writer : m_writers)
61 {
62 writer->PreFlushFrameCommandBuffer();
63 }
64
65 auto result = VK_SUCCESS;
66 const auto& frame = m_frames[m_currentFrame];
67
68 result = m_context->device.vkEndCommandBuffer(frame.commandBuffer);
69 CHECKVULKANERROR(result);
70
71 //Submit command buffer
72 {
73 auto submitInfo = Framework::Vulkan::SubmitInfo();
74 submitInfo.commandBufferCount = 1;
75 submitInfo.pCommandBuffers = &frame.commandBuffer;
76 result = m_context->device.vkQueueSubmit(m_context->queue, 1, &submitInfo, frame.execCompleteFence);
77 CHECKVULKANERROR(result);
78 }
79
80 for(const auto& writer : m_writers)
81 {
82 writer->PostFlushFrameCommandBuffer();
83 }
84
85 m_currentFrame++;
86 m_currentFrame %= MAX_FRAMES;
87 }
88
Flush()89 void CFrameCommandBuffer::Flush()
90 {
91 EndFrame();
92 BeginFrame();
93 m_flushCount++;
94 }
95
GetFlushCount() const96 uint32 CFrameCommandBuffer::GetFlushCount() const
97 {
98 return m_flushCount;
99 }
100
ResetFlushCount()101 void CFrameCommandBuffer::ResetFlushCount()
102 {
103 m_flushCount = 0;
104 }
105
GetCommandBuffer()106 VkCommandBuffer CFrameCommandBuffer::GetCommandBuffer()
107 {
108 const auto& frame = m_frames[m_currentFrame];
109 return frame.commandBuffer;
110 }
111
GetCurrentFrame() const112 uint32 CFrameCommandBuffer::GetCurrentFrame() const
113 {
114 return m_currentFrame;
115 }
116