-
Notifications
You must be signed in to change notification settings - Fork 0
/
generic_app.cpp
127 lines (104 loc) · 4.62 KB
/
generic_app.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "generic_app.hpp"
#include "spock_pipeline.hpp"
#include <vulkan/vulkan_core.h>
// std
#include <stdexcept>
#include <cstdint>
#include <exception>
#include <memory>
#include <array>
namespace spock {
GenericApp::GenericApp() {
createPipelineLayout();
createPipeline();
createCommandBuffers();
}
GenericApp::~GenericApp() {
vkDestroyPipelineLayout(spockDevice.device(), pipelineLayout, nullptr);
}
void GenericApp::run() {
while (!spockWindow.shouldClose()) {
glfwPollEvents();
drawFrame();
}
}
void GenericApp::createPipelineLayout() {
VkPipelineLayoutCreateInfo pipelineLayoutInfo {};
pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
pipelineLayoutInfo.setLayoutCount = 0;
pipelineLayoutInfo.pSetLayouts = nullptr;
pipelineLayoutInfo.pushConstantRangeCount = 0;
pipelineLayoutInfo.pPushConstantRanges = nullptr;
if (
vkCreatePipelineLayout(
spockDevice.device(),
&pipelineLayoutInfo,
nullptr,
&pipelineLayout
) != VK_SUCCESS
) {
throw std::runtime_error("Failed to create pipeline layout");
}
}
void GenericApp::createPipeline() {
PipelineConfigInfo pipelineConfig = SpockPipeline::defaultPipelineConfigInfo(spockSwapchain.width(), spockSwapchain.height());
// consider extracting getRenderPass to a dedicated class
pipelineConfig.renderPass = spockSwapchain.getRenderPass();
pipelineConfig.pipelineLayout = pipelineLayout;
spockPipeline = std::make_unique<SpockPipeline>(
spockDevice,
"shaders/simple_shader.vert.spv",
"shaders/simple_shader.frag.spv",
pipelineConfig
);
}
void GenericApp::createCommandBuffers() {
commandBuffers.resize(spockSwapchain.imageCount());
VkCommandBufferAllocateInfo allocInfo {};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandPool = spockDevice.getCommandPool();
allocInfo.commandBufferCount = static_cast<uint32_t>(commandBuffers.size());
if (vkAllocateCommandBuffers(spockDevice.device(), &allocInfo, commandBuffers.data()) != VK_SUCCESS) {
throw std::runtime_error("Failed to allocate command buffers");
}
for (int i = 0; i < commandBuffers.size(); i++) {
VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
if (vkBeginCommandBuffer(commandBuffers[i], &beginInfo) != VK_SUCCESS) {
throw std::runtime_error("Failed to begin command buffer");
}
VkRenderPassBeginInfo renderPassInfo {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = spockSwapchain.getRenderPass();
renderPassInfo.framebuffer = spockSwapchain.getFrameBuffer(i);
renderPassInfo.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = spockSwapchain.getSwapchainExtent();
std::array<VkClearValue, 2> clearValues {};
clearValues[0].color = { 0.1f, 0.1f, 0.1f, 1.0f };
clearValues[1].depthStencil = { 1.0f, 0 };
renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
renderPassInfo.pClearValues = clearValues.data();
vkCmdBeginRenderPass(commandBuffers[i], &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
spockPipeline->bind(commandBuffers[i]);
// record draw command
vkCmdDraw(commandBuffers[i], 3, 1, 0, 0);
vkCmdEndRenderPass(commandBuffers[i]);
if (vkEndCommandBuffer(commandBuffers[i]) != VK_SUCCESS) {
throw std::runtime_error("Failed to end command buffer");
}
}
};
void GenericApp::drawFrame() {
uint32_t imageIndex;
VkResult result = spockSwapchain.acquireNextImage(&imageIndex);
// FIXME: handle VK_SUBOPTIMAL_KHR in case of window resize
if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) {
throw std::runtime_error("Failed to acquire swapchain image");
}
result = spockSwapchain.submitCommandBuffers(&commandBuffers[imageIndex], &imageIndex);
if (result != VK_SUCCESS) {
throw std::runtime_error("Failed to present swapchain image");
}
};
} // namespace spock