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