FastEngine 0.9.4
A multiplayer oriented 2D engine made with Vulkan.
Loading...
Searching...
No Matches
C_context.hpp
1/*
2 * Copyright 2025 Guillaume Guillet
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef _FGE_VULKAN_C_CONTEXT_HPP_INCLUDED
18#define _FGE_VULKAN_C_CONTEXT_HPP_INCLUDED
19
20#include "FastEngine/fge_extern.hpp"
21
22#include "FastEngine/vulkan/vulkanGlobal.hpp"
23#include <array>
24#include <unordered_map>
25#include <vector>
26
27#include "FastEngine/vulkan/C_commandBuffer.hpp"
28#include "FastEngine/vulkan/C_descriptorPool.hpp"
29#include "FastEngine/vulkan/C_descriptorSetLayout.hpp"
30#include "FastEngine/vulkan/C_garbageCollector.hpp"
31#include "FastEngine/vulkan/C_graphicPipeline.hpp"
32#include "FastEngine/vulkan/C_instance.hpp"
33#include "FastEngine/vulkan/C_logicalDevice.hpp"
34#include "FastEngine/vulkan/C_physicalDevice.hpp"
35#include "FastEngine/vulkan/C_surface.hpp"
36#include "FastEngine/vulkan/C_textureImage.hpp"
37#include "FastEngine/vulkan/C_uniformBuffer.hpp"
38
41#define FGE_VULKAN_USE_STRICT_LAYOUT_BINDINGS_STAGE 0
42
43#define FGE_VULKAN_TEXTURE_BINDING 0
44#define FGE_VULKAN_TRANSFORM_BINDING 0
45#define FGE_MULTIUSE_POOL_MAX_COMBINED_IMAGE_SAMPLER FGE_SHADER_MAX_BINDING_VARIABLE_DESCRIPTOR_COUNT
46
47#define FGE_CONTEXT_OUTSIDE_RENDER_SCOPE_COMMAND_WAITSTAGE VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
48
49#define FGE_CONTEXT_GLOBALTRANSFORMS_COUNT_START 200
50
51namespace fge
52{
53
54struct TransformUboData;
55class RenderTarget;
56
57} // namespace fge
58
59namespace fge::vulkan
60{
61
69class FGE_API Context
70{
71public:
77
78 class SubmitableCommandBuffer : public CommandBuffer
79 {
80 public:
81 using CommandBuffer::CommandBuffer;
82
83 [[nodiscard]] inline SubmitTypes getSubmitType() const { return g_submitType; }
84
85 private:
86 inline void setSubmitType(SubmitTypes type) { this->g_submitType = type; }
87
88 SubmitTypes g_submitType;
89
90 friend class Context;
91 };
92
93 struct GlobalTransform
94 {
95 GlobalTransform(vulkan::Context const& context);
96
97 void init(vulkan::Context const& context);
98 void update();
99
100 vulkan::UniformBuffer _transforms;
101 vulkan::DescriptorSet _descriptorSet;
102 uint32_t _transformsCount;
103 bool _needUpdate;
104 };
105
106 Context();
114 explicit Context(Surface const& surface);
115 Context(Context const& r) = delete;
116 Context(Context&& r) noexcept = delete;
117 ~Context();
118
119 Context& operator=(Context const& r) = delete;
120 Context& operator=(Context&& r) noexcept = delete;
121
122 void destroy();
123
152 CommandBuffer::RenderPassScopes wantedRenderPassScope,
153 CommandBuffer::SupportedQueueTypes_t wantedQueue) const;
162
172 [[nodiscard]] VkSemaphore getIndirectSemaphore() const;
186 void submit() const;
187
204 [[nodiscard]] static Instance init(uint32_t sdlFlag,
205 std::string_view applicationName,
206 uint16_t versionMajor = 1,
207 uint16_t versionMinor = 0,
208 uint16_t versionPatch = 0);
209
215 static void initVolk();
216
225 void initVulkan(Surface const& surface);
226 void initVulkanSurfaceless(Instance const& instance);
227
233 static void enumerateExtensions();
239 [[nodiscard]] static std::vector<std::string> retrieveExtensions();
240
247 void waitIdle();
248
249 [[nodiscard]] Instance const& getInstance() const;
250 [[nodiscard]] Surface const& getSurface() const;
251 [[nodiscard]] LogicalDevice const& getLogicalDevice() const;
252 [[nodiscard]] PhysicalDevice const& getPhysicalDevice() const;
253
264 [[nodiscard]] VkCommandPool getGraphicsCommandPool() const;
276 void allocateGraphicsCommandBuffers(VkCommandBufferLevel level,
277 VkCommandBuffer commandBuffers[],
278 uint32_t commandBufferCount) const;
279
291 [[nodiscard]] DescriptorPool const& getMultiUseDescriptorPool() const;
292
305 [[nodiscard]] DescriptorSetLayout const& getTextureLayout() const;
318 [[nodiscard]] DescriptorSetLayout const& getTransformLayout() const;
326 [[nodiscard]] DescriptorPool const& getTextureDescriptorPool() const;
334 [[nodiscard]] DescriptorPool const& getTransformDescriptorPool() const;
335
341 [[nodiscard]] VmaAllocator getAllocator() const;
342
343 [[nodiscard]] std::optional<BufferInfo> createBuffer(VkDeviceSize size,
344 VkBufferUsageFlags usage,
345 VmaAllocationCreateFlags flags,
346 VkMemoryPropertyFlags requiredProperties = 0) const;
347 [[nodiscard]] std::optional<ImageInfo> createImage(uint32_t width,
348 uint32_t height,
349 VkFormat format,
350 VkImageTiling tiling,
351 uint32_t mipLevels,
352 VkImageUsageFlags usage,
353 VmaAllocationCreateFlags flags,
354 VkMemoryPropertyFlags requiredProperties = 0) const;
355
365 void pushGraphicsCommandBuffer(VkCommandBuffer commandBuffer) const;
373 [[nodiscard]] std::vector<VkCommandBuffer> const& getGraphicsCommandBuffers() const;
380
381 void startMainRenderTarget(RenderTarget& renderTarget) const;
382 [[nodiscard]] RenderTarget* getMainRenderTarget() const;
383 [[nodiscard]] bool isMainRenderTarget(RenderTarget const& renderTarget) const;
384 void endMainRenderTarget(RenderTarget const& renderTarget) const;
385
386 [[nodiscard]] GlobalTransform const& getGlobalTransform() const;
387 [[nodiscard]] fge::TransformUboData const* getGlobalTransform(uint32_t index) const;
388 [[nodiscard]] std::pair<uint32_t, fge::TransformUboData*> requestGlobalTransform() const;
389
390 void clearLayoutPipelineCache() const;
403 [[nodiscard]] LayoutPipeline&
404 requestLayoutPipeline(Shader const* vertexShader, Shader const* geometryShader, Shader const* fragmentShader) const;
405 void clearDescriptorLayoutCache() const;
418 [[nodiscard]] std::vector<DescriptorSetLayout> const* requestDescriptorLayout(Shader const* vertexShader,
419 Shader const* geometryShader,
420 Shader const* fragmentShader) const;
421 [[nodiscard]] std::vector<DescriptorSetLayout> const* requestDescriptorLayout(Shader const* shader) const;
422
434 [[nodiscard]] std::optional<DescriptorSet>
435 createDescriptorSet(std::string_view shaderName, uint32_t setIndex, uint32_t variableElements = 0) const;
436
437 GarbageCollector _garbageCollector;
438
439private:
440 void createCommandPool();
441 void createMultiUseDescriptorPool();
442 void createTextureDescriptorPool();
443 void createTransformDescriptorPool();
444 void createSyncObjects();
445
446 mutable GlobalTransform g_globalTransform;
447
448 struct ReusableCommandBuffer
449 {
450 constexpr ReusableCommandBuffer() = default;
451 constexpr ReusableCommandBuffer(VkCommandBuffer commandBuffer, bool isRecording) :
452 _commandBuffer(commandBuffer),
453 _isRecording(isRecording)
454 {}
455
456 VkCommandBuffer _commandBuffer{VK_NULL_HANDLE};
457 bool _isRecording{false};
458 };
459
460 PhysicalDevice g_physicalDevice;
461 LogicalDevice g_logicalDevice;
462 Surface const* g_surface;
463 Instance const* g_instance;
464
465 mutable std::unordered_map<LayoutPipeline::Key,
466 std::vector<DescriptorSetLayout>,
467 LayoutPipeline::Key::Hash,
468 LayoutPipeline::Key::Compare>
469 g_cacheDescriptorLayouts;
470 mutable std::
471 unordered_map<LayoutPipeline::Key, LayoutPipeline, LayoutPipeline::Key::Hash, LayoutPipeline::Key::Compare>
472 g_cachePipelineLayouts;
473 DescriptorPool g_multiUseDescriptorPool;
474
475 DescriptorSetLayout g_textureLayout;
476 DescriptorSetLayout g_transformLayout;
477 DescriptorPool g_textureDescriptorPool;
478 DescriptorPool g_transformDescriptorPool;
479
480 mutable RenderTarget* g_mainRenderTarget;
481
482 mutable VmaAllocator g_allocator;
483
484 mutable uint32_t g_currentFrame;
485
486 mutable std::vector<VkCommandBuffer> g_graphicsSubmitableCommandBuffers;
487
488 std::array<VkSemaphore, FGE_MAX_FRAMES_IN_FLIGHT> g_indirectFinishedSemaphores{};
489 mutable std::array<std::vector<CommandBuffer>, FGE_MAX_FRAMES_IN_FLIGHT> g_indirectSubmitableCommandBuffers{};
490 mutable std::array<ReusableCommandBuffer, FGE_MAX_FRAMES_IN_FLIGHT>
491 g_indirectOutsideRenderScopeGraphicsSubmitableCommandBuffers{};
492
493 VkCommandPool g_graphicsCommandPool;
494 bool g_isCreated;
495};
496
497} // namespace fge::vulkan
498
499#endif //_FGE_VULKAN_C_CONTEXT_HPP_INCLUDED
Definition C_renderTarget.hpp:56
Vulkan context.
Definition C_context.hpp:70
std::vector< VkCommandBuffer > const & getGraphicsCommandBuffers() const
Retrieve the list of submitable graphics command buffers.
DescriptorPool const & getMultiUseDescriptorPool() const
Retrieve a "multi-usage" descriptor pool.
SubmitTypes
Definition C_context.hpp:73
@ INDIRECT_EXECUTION
The command buffer is transferred to a queue in order to be submitted later and will always be execut...
Definition C_context.hpp:75
@ DIRECT_WAIT_EXECUTION
The command buffer is submitted directly to the queue and vkQueueWaitIdle is called.
Definition C_context.hpp:74
static void enumerateExtensions()
Enumerate to standard output the available extensions.
LayoutPipeline & requestLayoutPipeline(Shader const *vertexShader, Shader const *geometryShader, Shader const *fragmentShader) const
Retrieve a layout pipeline.
void waitIdle()
Wait for the device to be idle.
DescriptorPool const & getTransformDescriptorPool() const
Retrieve a "transform" descriptor pool.
std::vector< DescriptorSetLayout > const * requestDescriptorLayout(Shader const *vertexShader, Shader const *geometryShader, Shader const *fragmentShader) const
Retrieve a descriptor set layout.
void initVulkan(Surface const &surface)
Initialize Vulkan.
void pushGraphicsCommandBuffer(VkCommandBuffer commandBuffer) const
Push a graphics command buffer to a list.
static std::vector< std::string > retrieveExtensions()
Retrieve the available extensions.
Context(Surface const &surface)
Shortcut to initVulkan(surface)
DescriptorSetLayout const & getTextureLayout() const
Retrieve a "texture" descriptor set layout.
bool submitCommands(SubmitableCommandBuffer &&buffer) const
Submit commands.
static void initVolk()
Initialize Volk (Vulkan loader)
void clearGraphicsCommandBuffers() const
Clear the list of submitable graphics command buffers.
std::optional< DescriptorSet > createDescriptorSet(std::string_view shaderName, uint32_t setIndex, uint32_t variableElements=0) const
Helper to request a descriptor set.
void allocateGraphicsCommandBuffers(VkCommandBufferLevel level, VkCommandBuffer commandBuffers[], uint32_t commandBufferCount) const
Allocate graphics command buffers.
void submit() const
Submit Context command buffers.
VmaAllocator getAllocator() const
Retrieve the VMA (Vulkan Memory Allocator)
VkCommandPool getGraphicsCommandPool() const
Retrieve a command pool for graphics commands.
static Instance init(uint32_t sdlFlag, std::string_view applicationName, uint16_t versionMajor=1, uint16_t versionMinor=0, uint16_t versionPatch=0)
Helper to init SDL, volk and create an Instance.
VkSemaphore getIndirectSemaphore() const
Retrieve the semaphore that is signaled when all indirect command buffers have finished executing.
SubmitableCommandBuffer beginCommands(SubmitTypes type, CommandBuffer::RenderPassScopes wantedRenderPassScope, CommandBuffer::SupportedQueueTypes_t wantedQueue) const
Begin commands.
DescriptorPool const & getTextureDescriptorPool() const
Retrieve a "texture" descriptor pool.
DescriptorSetLayout const & getTransformLayout() const
Retrieve a "transform" descriptor set layout.
This class abstract the vulkan descriptor pool for easier use.
Definition C_descriptorPool.hpp:41
This class abstract the vulkan descriptor set layout for easier use.
Definition C_descriptorSetLayout.hpp:38
This class abstract the vulkan descriptor set for easier use.
Definition C_descriptorSet.hpp:41
A garbage collector for Vulkan objects.
Definition C_garbageCollector.hpp:304
Vulkan instance abstraction.
Definition C_instance.hpp:39
Definition C_graphicPipeline.hpp:35
Logical device abstraction.
Definition C_logicalDevice.hpp:37
Vulkan physical device abstraction.
Definition C_physicalDevice.hpp:34
Definition vulkan/C_shader.hpp:36
Vulkan surface abstraction.
Definition vulkan/C_surface.hpp:42
Definition C_uniformBuffer.hpp:32
Definition C_transform.hpp:26
Definition C_context.hpp:94