Hymn to Beauty
C++ 3D Engine
VulkanRenderer.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "../Interface/LowLevelRenderer.hpp"
4
5#include <vulkan/vulkan.h>
6#include <map>
7#include <vector>
8#include "../Interface/ShaderProgram.hpp"
10
11namespace Utility {
12class Window;
13}
14
15namespace Video {
16
17class VulkanBuffer;
18class VulkanBufferAllocator;
19class VulkanRenderPassAllocator;
20class VulkanRenderTargetAllocator;
21class VulkanSampler;
22
25 public:
27
30 explicit VulkanRenderer(::Utility::Window* window);
31
33 ~VulkanRenderer() final;
34
36 void BeginFrame() final;
37 void Submit(CommandBuffer* commandBuffer) final;
38 void Present() final;
39 Buffer* CreateBuffer(Buffer::BufferUsage bufferUsage, uint32_t size, const void* data = nullptr) final;
40 Buffer* CreateTemporaryBuffer(Buffer::BufferUsage bufferUsage, uint32_t size, const void* data = nullptr) final;
41 VertexDescription* CreateVertexDescription(unsigned int attributeCount, const VertexDescription::Attribute* attributes, bool indexBuffer = false) final;
42 GeometryBinding* CreateGeometryBinding(const VertexDescription* vertexDescription, Buffer* vertexBuffer, GeometryBinding::IndexType indexType = GeometryBinding::IndexType::NONE, const Buffer* indexBuffer = nullptr) final;
43 Shader* CreateShader(const ShaderSource& shaderSource, Shader::Type type) final;
44 ShaderProgram* CreateShaderProgram(std::initializer_list<const Shader*> shaders) final;
45 Texture* CreateTexture(const glm::uvec2 size, Texture::Format format, int components, unsigned char* data) final;
46 const Sampler* GetSampler(Sampler::Filter filter, Sampler::Clamping clamping) const final;
47 Texture* CreateRenderTarget(const glm::uvec2& size, Texture::Format format) final;
48 void FreeRenderTarget(Texture* renderTarget) final;
49 GraphicsPipeline* CreateGraphicsPipeline(const ShaderProgram* shaderProgram, const GraphicsPipeline::Configuration& configuration, const VertexDescription* vertexDescription = nullptr) final;
50 ComputePipeline* CreateComputePipeline(const ShaderProgram* shaderProgram) final;
51 void Wait() final;
52 unsigned char* ReadImage(Texture* texture) final;
53 const std::vector<Profiling::Event>& GetTimeline() const final;
54 const OptionalFeatures& GetOptionalFeatures() const final;
55
57
60 VkImage GetCurrentSwapChainImage() const;
61
63
66 uint32_t GetSwapChainImageCount() const;
67
69 VkDescriptorSetLayout GetEmptyDescriptorSetLayout() const;
70
72
77 VkDescriptorSetLayout GetBufferDescriptorSetLayout(ShaderProgram::BindingType bindingType) const;
78
80
85 VkDescriptorSetLayout GetStorageBufferDescriptorSetLayout(unsigned int buffers) const;
86
88
93 VkDescriptorSetLayout GetMaterialDescriptorSetLayout(unsigned int textures) const;
94
96
102 VkDescriptorSet GetDescriptorSet(ShaderProgram::BindingType bindingType, VulkanBuffer* buffer);
103
105
110 VkDescriptorSet GetStorageBufferDescriptorSet(std::initializer_list<Buffer*> buffers);
111
113
118 VkDescriptorSet GetDescriptorSet(std::initializer_list<std::pair<Texture*, const Sampler*>> textures);
119
121
124 VkQueryPool GetQueryPool();
125
127
130 uint32_t GetFreeQuery();
131
132 private:
133 VulkanRenderer(const VulkanRenderer& other) = delete;
134
135 void CreateInstance();
136 bool CheckValidationLayersSupported(const std::vector<const char*>& validationLayers) const;
137
138 void CreateSurface(::Utility::Window* window);
139
140 struct SwapChainSupport {
141 VkSurfaceCapabilitiesKHR capabilities;
142 std::vector<VkSurfaceFormatKHR> formats;
143 std::vector<VkPresentModeKHR> presentModes;
144 };
145
146 void CreateDevice(SwapChainSupport& swapChainSupport);
147 VkPhysicalDevice PickPhysicalDevice(const std::vector<const char*>& extensions) const;
148 uint32_t GetDeviceScore(VkPhysicalDevice device, const std::vector<const char*>& extensions) const;
149 bool CheckDeviceExtensionsSupported(VkPhysicalDevice device, const std::vector<const char*>& extensions) const;
150 uint32_t GetQueueFamily(VkPhysicalDevice device) const;
151 SwapChainSupport GetSwapChainSupport(VkPhysicalDevice device) const;
152 const std::vector<const char*> GetEnabledExtensions(const std::vector<const char*>& mandatoryExtensions);
153 VkPhysicalDeviceFeatures GetEnabledFeatures();
154
155 void CreateSwapChain(const SwapChainSupport& swapChainSupport);
156 void FreeSwapChain();
157 void RecreateSwapChain();
158 VkSurfaceFormatKHR ChooseSurfaceFormat(const SwapChainSupport& swapChainSupport) const;
159 VkPresentModeKHR ChoosePresentMode(const SwapChainSupport& swapChainSupport) const;
160 VkExtent2D ChooseExtent(const SwapChainSupport& swapChainSupport) const;
161
162 void CreateImageViews();
163
164 void CreateSyncObjects();
165
166 void CreateCommandPool();
167
168 void CreateBakedDescriptorSetLayouts();
169 void CreateDescriptorPool();
170
171 void CreateQueries();
172 void ResetQueries(uint32_t queryPool);
173
174 void CreateSamplers();
175
176 void AcquireSwapChainImage();
177
178 VkInstance instance;
179 VkPhysicalDevice physicalDevice;
180 VkDevice device;
181
182 uint32_t graphicsQueueFamily;
183 VkQueue queue;
184
185 VkSurfaceKHR surface;
186 VkSwapchainKHR swapChain;
187 std::vector<VkImage> swapChainImages;
188 VkFormat swapChainImageFormat;
189 VkExtent2D swapChainExtent;
190 std::vector<VkImageView> swapChainImageViews;
191
192 uint32_t imageIndex;
193 uint32_t currentFrame = 0;
194 std::vector<VkSemaphore> imageAvailableSemaphores;
195 std::vector<VkSemaphore> renderFinishedSemaphores;
196 std::vector<VkFence> renderFinishedFences;
197 VkFence recreateFence;
198
199 VkCommandPool commandPool;
200
201 VulkanBufferAllocator* bufferAllocator;
202 uint32_t nonCoherentAtomSize;
203
204 VulkanRenderPassAllocator* renderPassAllocator;
205 VulkanRenderTargetAllocator* renderTargetAllocator;
206
207 VkDescriptorSetLayout emptyDescriptorSetLayout;
208 VkDescriptorSetLayout bufferDescriptorSetLayouts[ShaderProgram::BindingType::BINDING_TYPES];
209 std::vector<std::map<ShaderProgram::BindingType, std::vector<VkDescriptorSet>>> bufferDescriptorSetCache;
210 unsigned int currentBufferDescriptorSet[ShaderProgram::BindingType::BINDING_TYPES];
211
212 static const unsigned int bakedStorageBufferDescriptorSetLayouts = 16;
213 VkDescriptorSetLayout storageBufferDescriptorSetLayouts[bakedStorageBufferDescriptorSetLayouts];
214 std::vector<std::map<VkDescriptorSetLayout, std::vector<VkDescriptorSet>>> storageBufferDescriptorSetCache;
215 unsigned int currentStorageBufferDescriptorSet[bakedStorageBufferDescriptorSetLayouts];
216
217 static const unsigned int bakedMaterialDescriptorSetLayouts = 16;
218 VkDescriptorSetLayout materialDescriptorSetLayouts[bakedMaterialDescriptorSetLayouts];
219 std::vector<std::map<VkDescriptorSetLayout, std::vector<VkDescriptorSet>>> materialDescriptorSetCache;
220 unsigned int currentMaterialDescriptorSet[bakedMaterialDescriptorSetLayouts];
221
222 VkDescriptorPool descriptorPool;
223
224 VulkanSampler* samplers[static_cast<uint32_t>(Sampler::Filter::COUNT) * static_cast<uint32_t>(Sampler::Clamping::COUNT)];
225
226 OptionalFeatures optionalFeatures;
227
228 double timestampPeriod;
229 static const unsigned int maxQueries = 2 * 50;
230 std::vector<VkQueryPool> queryPools;
231 std::vector<Profiling::Event> finishedEvents;
232 std::vector<uint32_t> currentQuery;
233 VkCommandBuffer* queryCommandBuffers;
234 VkSemaphore* queryResetSemaphores;
235 bool firstSubmission;
236 bool* needQueryWait;
237 std::vector<VulkanCommandBuffer::Timing>* submittedTimings;
238 uint64_t results[maxQueries];
239 double* submissionTimes;
240};
241
242} // namespace Video
Definition: Window.hpp:14
A buffer containing GPU accessible data.
Definition: Buffer.hpp:8
BufferUsage
How the buffer is going to be used.
Definition: Buffer.hpp:11
A buffer into which rendering commands are recorded.
Definition: CommandBuffer.hpp:24
A compute pipeline.
Definition: ComputePipeline.hpp:11
Binds together a vertex description with buffers.
Definition: GeometryBinding.hpp:8
IndexType
The type of values in the index buffer.
Definition: GeometryBinding.hpp:11
A graphics pipeline.
Definition: GraphicsPipeline.hpp:11
Low level renderer abstracting the underlaying graphics API (OpenGL or Vulkan).
Definition: LowLevelRenderer.hpp:27
Determines how a texture should be sampled.
Definition: Sampler.hpp:6
Filter
The interpolation to apply.
Definition: Sampler.hpp:9
@ COUNT
Number of entries in enum.
Clamping
How to handle sampling outside the texture dimensions.
Definition: Sampler.hpp:16
@ COUNT
Number of entries in enum.
Compiles and handles a shader. Shaders should be linked together into a ShaderProgram.
Definition: Shader.hpp:8
Type
The type of shader.
Definition: Shader.hpp:11
A shader program.
Definition: ShaderProgram.hpp:11
BindingType
A type of bound resource.
Definition: ShaderProgram.hpp:14
A texture.
Definition: Texture.hpp:8
Format
The format of the texture.
Definition: Texture.hpp:18
Describes how a vertex buffer is accessed by a shader.
Definition: VertexDescription.hpp:8
Vulkan implementation of BufferAllocator.
Definition: VulkanBufferAllocator.hpp:51
Vulkan implementation of Buffer.
Definition: VulkanBuffer.hpp:13
Vulkan implementation of RenderPassAllocator.
Definition: VulkanRenderPassAllocator.hpp:9
Vulkan implementation of RenderTargetAllocator.
Definition: VulkanRenderTargetAllocator.hpp:12
Low-level renderer implementing Vulkan.
Definition: VulkanRenderer.hpp:24
void Wait() final
Wait for all rendering to finish.
Definition: VulkanRenderer.cpp:309
Texture * CreateRenderTarget(const glm::uvec2 &size, Texture::Format format) final
Create a render target.
Definition: VulkanRenderer.cpp:293
uint32_t GetFreeQuery()
Get a free query from the current frame's pool.
Definition: VulkanRenderer.cpp:571
VkImage GetCurrentSwapChainImage() const
Get current swap chain image.
Definition: VulkanRenderer.cpp:379
const std::vector< Profiling::Event > & GetTimeline() const final
Get profiling timeline.
Definition: VulkanRenderer.cpp:371
VulkanRenderer(::Utility::Window *window)
Create new Vulkan renderer.
Definition: VulkanRenderer.cpp:35
void FreeRenderTarget(Texture *renderTarget) final
Free a render target.
Definition: VulkanRenderer.cpp:297
ShaderProgram * CreateShaderProgram(std::initializer_list< const Shader * > shaders) final
Create a shader program.
Definition: VulkanRenderer.cpp:276
GraphicsPipeline * CreateGraphicsPipeline(const ShaderProgram *shaderProgram, const GraphicsPipeline::Configuration &configuration, const VertexDescription *vertexDescription=nullptr) final
Create a graphics pipeline.
Definition: VulkanRenderer.cpp:301
VkDescriptorSetLayout GetMaterialDescriptorSetLayout(unsigned int textures) const
Get the descriptor set layout for a material binding.
Definition: VulkanRenderer.cpp:404
VkQueryPool GetQueryPool()
Get the current frame's query pool.
Definition: VulkanRenderer.cpp:565
uint32_t GetSwapChainImageCount() const
Get the number of swap chain images.
Definition: VulkanRenderer.cpp:383
GeometryBinding * CreateGeometryBinding(const VertexDescription *vertexDescription, Buffer *vertexBuffer, GeometryBinding::IndexType indexType=GeometryBinding::IndexType::NONE, const Buffer *indexBuffer=nullptr) final
Create a geometry binding.
Definition: VulkanRenderer.cpp:268
void BeginFrame() final
Begin a new frame.
Definition: VulkanRenderer.cpp:134
ComputePipeline * CreateComputePipeline(const ShaderProgram *shaderProgram) final
Create a compute pipeline.
Definition: VulkanRenderer.cpp:305
VkDescriptorSetLayout GetStorageBufferDescriptorSetLayout(unsigned int buffers) const
Get the descriptor set layout for a storage buffer binding.
Definition: VulkanRenderer.cpp:397
Texture * CreateTexture(const glm::uvec2 size, Texture::Format format, int components, unsigned char *data) final
Create a texture.
Definition: VulkanRenderer.cpp:280
Buffer * CreateTemporaryBuffer(Buffer::BufferUsage bufferUsage, uint32_t size, const void *data=nullptr) final
Definition: VulkanRenderer.cpp:260
VkDescriptorSet GetDescriptorSet(ShaderProgram::BindingType bindingType, VulkanBuffer *buffer)
Get a descriptor set for a given binding type and buffer.
Definition: VulkanRenderer.cpp:410
Shader * CreateShader(const ShaderSource &shaderSource, Shader::Type type) final
Create a shader.
Definition: VulkanRenderer.cpp:272
VertexDescription * CreateVertexDescription(unsigned int attributeCount, const VertexDescription::Attribute *attributes, bool indexBuffer=false) final
Create a vertex description.
Definition: VulkanRenderer.cpp:264
void Present() final
Present the rendered image to the swap chain.
Definition: VulkanRenderer.cpp:243
VkDescriptorSetLayout GetBufferDescriptorSetLayout(ShaderProgram::BindingType bindingType) const
Get the descriptor set layout for a buffer binding.
Definition: VulkanRenderer.cpp:391
Buffer * CreateBuffer(Buffer::BufferUsage bufferUsage, uint32_t size, const void *data=nullptr) final
Definition: VulkanRenderer.cpp:256
VkDescriptorSet GetStorageBufferDescriptorSet(std::initializer_list< Buffer * > buffers)
Get a descriptor set for a given binding of storage buffers.
Definition: VulkanRenderer.cpp:464
VkDescriptorSetLayout GetEmptyDescriptorSetLayout() const
Get the empty descriptor set layout.
Definition: VulkanRenderer.cpp:387
const Sampler * GetSampler(Sampler::Filter filter, Sampler::Clamping clamping) const final
Get a sampler.
Definition: VulkanRenderer.cpp:286
~VulkanRenderer() final
Destructor.
Definition: VulkanRenderer.cpp:71
const OptionalFeatures & GetOptionalFeatures() const final
Get which optional features are supported.
Definition: VulkanRenderer.cpp:375
CommandBuffer * CreateCommandBuffer() final
Create a command buffer.
Definition: VulkanRenderer.cpp:130
void Submit(CommandBuffer *commandBuffer) final
Submit a command buffer for execution.
Definition: VulkanRenderer.cpp:188
unsigned char * ReadImage(Texture *texture) final
Read a render texture color image.
Definition: VulkanRenderer.cpp:313
Vulkan implementation of Sampler.
Definition: VulkanSampler.hpp:12
Definition: ResourceView.hpp:12
Definition: Editor.hpp:18
The configuration of the graphics pipeline.
Definition: GraphicsPipeline.hpp:14
Optional features.
Definition: LowLevelRenderer.hpp:30
Describes an attribute used in a vertex shader.
Definition: VertexDescription.hpp:18