53 , m_surface(s_instance, window)
54 , m_physicalDevice(*
Si::Vulkan::PhysicalDevice::getBest(
58 {
"VK_KHR_portability_subset",
false },
59 { VK_KHR_SWAPCHAIN_EXTENSION_NAME }
61 , m_device(m_physicalDevice)
62 , m_swapChain(m_device, window, m_surface)
63 , m_renderPass(m_device)
64 , m_pipeline(m_renderPass)
65 , m_commandPool(m_device)
66 , m_vertexBuffer(s_instance, m_device,
sizeof(
Si::Vertex) * 3)
75 m_maxFrames = imageViews.
size();
77 vk::CommandBufferAllocateInfo commandBufferAllocateInfo { *m_commandPool, vk::CommandBufferLevel::ePrimary,
static_cast<uint32_t
>(m_maxFrames) };
80 m_fences.reserve(m_maxFrames);
81 m_framebuffers.reserve(m_maxFrames);
82 m_imageAvailableSemaphores.reserve(m_maxFrames);
83 m_renderFinishedSemaphores.reserve(m_maxFrames);
85 for (
unsigned i = 0; i < m_maxFrames; i++) {
86 m_fences.emplace_back(m_device);
87 m_fences.back().create();
89 m_framebuffers.emplace_back(m_renderPass, imageViews[i], m_swapChain);
90 m_framebuffers.back().create();
92 m_imageAvailableSemaphores.emplace_back(m_device);
93 m_imageAvailableSemaphores.back().create();
95 m_renderFinishedSemaphores.emplace_back(m_device);
96 m_renderFinishedSemaphores.back().create();
107 if (result == vk::Result::eErrorOutOfDateKHR) {
110 }
else if ((result != vk::Result::eSuccess) && (result != vk::Result::eSuboptimalKHR)) {
115 m_device->resetFences(fences);
117 vk::CommandBuffer commandBuffer = m_commandBuffers[m_frameIndex];
119 vk::CommandBufferBeginInfo commandBufferBeginInfo { vk::CommandBufferUsageFlagBits::eOneTimeSubmit };
120 commandBuffer.begin(commandBufferBeginInfo);
122 vk::Viewport viewport {
125 static_cast<float>(m_swapChain.
getExtent().width),
126 static_cast<float>(m_swapChain.
getExtent().height),
131 vk::Rect2D scissor { { 0, 0 }, m_swapChain.
getExtent() };
133 commandBuffer.setViewport(0, { viewport });
134 commandBuffer.setScissor(0, { scissor });
136 vk::ClearValue clearValue { vk::ClearColorValue().setFloat32({ 0, 0, 0, 0 }) };
137 vk::RenderPassBeginInfo renderPassBeginInfo { *m_renderPass, *(m_framebuffers[imageIndex]), { { 0, 0 }, m_swapChain.
getExtent() }, clearValue };
138 commandBuffer.beginRenderPass(renderPassBeginInfo, vk::SubpassContents::eInline);
140 commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, *m_pipeline);
145 commandBuffer.bindVertexBuffers(0, vertexBuffers, vertexOffsets);
147 commandBuffer.draw(
m_vertices.size(), 1, 0, 0);
149 commandBuffer.endRenderPass();
158 vk::SubmitInfo submitInfo { waitSemaphores, waitStages, commandBuffers, signalSemaphores };
160 m_device.
getGraphicsQueue().submit({ submitInfo }, *m_fences[m_frameIndex]);
165 vk::PresentInfoKHR presentInfo { signalSemaphores, swapChains, imageIndices };
167 auto presentResult = m_device.
getPresentQueue().presentKHR(presentInfo);
169 if ((presentResult == vk::Result::eErrorOutOfDateKHR) || (presentResult == vk::Result::eSuboptimalKHR) || resize) {
172 }
else if (presentResult != vk::Result::eSuccess) {
177 ++m_frameIndex %= m_maxFrames;
184 m_device->waitIdle();
The Renderer class is the base class for all Renderer implementations.
Si::Vector< Si::Vertex > m_vertices
static void RegisterRenderer(const std::string &name, std::unique_ptr< Renderer > renderer)
Registers a renderer implementation with the renderer.
Handle wrapper for Vulkan Command Pool.
A class representing a GPU device.
vk::Queue getGraphicsQueue() const
Gets the graphics queue of the device.
vk::Queue getPresentQueue() const
Gets the present queue of the device.
void create()
Creates a handle.
A handle for Vulkan instances.
A class representing properties about a physical GPU.
Handle wrapper for Vulkan Pipeline.
Handle wrapper for Vulkan Render Pass.
Handle wrapper for Vulkan Surface.
Handle wrapper for Vulkan Swapchain.
Vector< ImageView > & getImageViews()
const vk::Extent2D & getExtent() const
VulkanRendererImpl(Si::Window &window)
void Error(Args &&... args)
void Create(Window &window)
boost::pool_allocator< T > Allocator