#pragma once #include #include #include #include "gfx.hpp" #include "gfx_vulkan_constants.hpp" class GFXVulkanCommandBuffer; struct NativeSurface { platform::window_ptr identifier = nullptr; uint32_t surfaceWidth = -1, surfaceHeight = -1; std::vector imageAvailableSemaphores; std::vector renderFinishedSemaphores; std::vector inFlightFences; size_t currentFrame = 0; VkSurfaceKHR surface = VK_NULL_HANDLE; VkSwapchainKHR swapchain = VK_NULL_HANDLE; VkExtent2D swapchainExtent = {}; std::vector swapchainImages; std::vector swapchainImageViews; VkRenderPass swapchainRenderPass = VK_NULL_HANDLE; std::vector swapchainFramebuffers; std::vector gfx_command_buffers; }; class GFXVulkanPipeline; class GFXVulkan : public GFX { public: bool is_supported() override { return true; } ShaderLanguage accepted_shader_language() override { return ShaderLanguage::SPIRV; } GFXContext required_context() override { return GFXContext::Vulkan; } const char* get_name() override; bool supports_feature(GFXFeature feature) override; bool initialize(const GFXCreateInfo& info) override; void initialize_view(void* native_handle, platform::window_ptr identifier, uint32_t width, uint32_t height) override; void recreate_view(platform::window_ptr identifier, uint32_t width, uint32_t height) override; // buffer operations GFXBuffer* create_buffer(void* data, GFXSize size, bool dynamic_data, GFXBufferUsage usage) override; void copy_buffer(GFXBuffer* buffer, void* data, GFXSize offset, GFXSize size) override; void* get_buffer_contents(GFXBuffer* buffer) override; void release_buffer_contents(GFXBuffer* buffer, void* handle) override; // texture operations GFXTexture* create_texture(const GFXTextureCreateInfo& info) override; void copy_texture(GFXTexture* texture, void* data, GFXSize size) override; void copy_texture(GFXTexture* from, GFXTexture* to) override; void copy_texture(GFXTexture* from, GFXBuffer* to) override; // sampler operations GFXSampler* create_sampler(const GFXSamplerCreateInfo& info) override; // framebuffer operations GFXFramebuffer* create_framebuffer(const GFXFramebufferCreateInfo& info) override; // render pass operations GFXRenderPass* create_render_pass(const GFXRenderPassCreateInfo& info) override; // pipeline operations GFXPipeline* create_graphics_pipeline(const GFXGraphicsPipelineCreateInfo& info) override; GFXPipeline* create_compute_pipeline(const GFXComputePipelineCreateInfo& info) override; // misc operations GFXSize get_alignment(GFXSize size) override; GFXCommandBuffer* acquire_command_buffer(bool for_presentation_use) override; void submit(GFXCommandBuffer* command_buffer, platform::window_ptr identifier) override; private: void createInstance(std::vector layers, std::vector extensions); void createLogicalDevice(std::vector extensions); void createSwapchain(NativeSurface* native_surface, VkSwapchainKHR oldSwapchain = VK_NULL_HANDLE); void createDescriptorPool(); void createSyncPrimitives(NativeSurface* native_surface); // dynamic descriptor sets void resetDescriptorState(); void cacheDescriptorState(GFXVulkanPipeline* pipeline, VkDescriptorSetLayout layout); uint64_t getDescriptorHash(GFXVulkanPipeline* pipeline); uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties); void transitionImageLayout(VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageSubresourceRange range, VkImageLayout oldLayout, VkImageLayout newLayout); void inlineTransitionImageLayout(VkCommandBuffer command_buffer, VkImage image, VkFormat format, VkImageAspectFlags aspect, VkImageSubresourceRange range, VkImageLayout oldLayout, VkImageLayout newLayout, VkPipelineStageFlags src_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VkPipelineStageFlags dst_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); VkShaderModule createShaderModule(const uint32_t* code, int length); VkCommandBuffer beginSingleTimeCommands(); void endSingleTimeCommands(VkCommandBuffer commandBuffer); VkInstance instance = VK_NULL_HANDLE; VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; VkDevice device = VK_NULL_HANDLE; VkQueue graphicsQueue = VK_NULL_HANDLE; VkQueue presentQueue = VK_NULL_HANDLE; VkCommandPool commandPool = VK_NULL_HANDLE; VkDescriptorPool descriptorPool = VK_NULL_HANDLE; std::vector native_surfaces; struct BoundShaderBuffer { GFXBuffer* buffer = nullptr; VkDeviceSize size = 0, offset = 0; }; std::array boundShaderBuffers; std::array boundTextures; std::array boundSamplers; };