From 72f5a6f834f7a2d40408d844483eadbd4b6f0722 Mon Sep 17 00:00:00 2001 From: Nikita Zuev Dmitrievich <44869886+reeegry@users.noreply.github.com> Date: Sun, 28 Sep 2025 23:29:15 +0300 Subject: [PATCH 1/3] Update codestyle.yml added manual run --- .github/workflows/codestyle.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml index 73247333..3586e6e5 100644 --- a/.github/workflows/codestyle.yml +++ b/.github/workflows/codestyle.yml @@ -14,6 +14,7 @@ on: - cmake/** - scripts/** - shaders/** + workflow_dispatch: jobs: cpp-linter: @@ -70,4 +71,4 @@ jobs: if: steps.linter.outputs.checks-failed > 0 run: | echo "cpp-linter found issues." - exit 1 \ No newline at end of file + exit 1 From bad2476d6dfc3a2c55c90a3f08513b41355d4816 Mon Sep 17 00:00:00 2001 From: Nikita Zuev <6u8654u4@gmail.com> Date: Mon, 29 Sep 2025 15:46:14 +0300 Subject: [PATCH 2/3] refact: styled project --- src/core/Mesh.cpp | 1 - src/graphics/vulkan/ComputePipeline.cpp | 45 ++-- src/graphics/vulkan/GraphicsPipeline.cpp | 60 ++--- src/graphics/vulkan/pipelines.cpp | 22 +- src/graphics/vulkan/vk_command_buffers.cpp | 49 +++-- .../vulkan/vk_command_buffers_container.cpp | 27 ++- src/graphics/vulkan/vk_engine.cpp | 206 ++++++++++-------- src/graphics/vulkan/vk_loader.cpp | 15 +- src/graphics/vulkan/vk_pipelines.cpp | 106 +++++---- src/include/graphics/vulkan/ComputePipeline.h | 25 ++- .../graphics/vulkan/GraphicsPipeline.h | 25 ++- src/include/graphics/vulkan/IPipeline.h | 4 +- src/include/graphics/vulkan/pipelines.h | 6 +- .../graphics/vulkan/vk_command_buffers.h | 7 +- .../vulkan/vk_command_buffers_container.h | 5 +- src/include/graphics/vulkan/vk_engine.h | 13 +- .../graphics/vulkan/vk_smart_wrappers.h | 142 ++++++++---- 17 files changed, 443 insertions(+), 315 deletions(-) diff --git a/src/core/Mesh.cpp b/src/core/Mesh.cpp index f496c69d..bb022490 100644 --- a/src/core/Mesh.cpp +++ b/src/core/Mesh.cpp @@ -34,7 +34,6 @@ void Mesh::remove_model() { } } - void Mesh::set_transform(glm::mat4 t) { VulkanEngine &engine = VulkanEngine::Get(); diff --git a/src/graphics/vulkan/ComputePipeline.cpp b/src/graphics/vulkan/ComputePipeline.cpp index 462ee47d..882ef9e6 100644 --- a/src/graphics/vulkan/ComputePipeline.cpp +++ b/src/graphics/vulkan/ComputePipeline.cpp @@ -1,48 +1,51 @@ #include "graphics/vulkan/ComputePipeline.h" + #include "graphics/vulkan/vk_initializers.h" -ComputePipeline::ComputePipeline(const ComputePipelineConfig& config) - : _config(config) { -} +ComputePipeline::ComputePipeline(const ComputePipelineConfig& config) + : _config(config) {} void ComputePipeline::init(VkDevice device) { _device = device; - + VkPipelineLayoutCreateInfo computeLayout{}; computeLayout.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; computeLayout.pNext = nullptr; computeLayout.pSetLayouts = &_config.descriptorSetLayout; computeLayout.setLayoutCount = 1; - VK_CHECK(vkCreatePipelineLayout(_device, &computeLayout, nullptr, &_pipelineLayout)); - + VK_CHECK(vkCreatePipelineLayout(_device, &computeLayout, nullptr, + &_pipelineLayout)); + VkShaderModule computeShader; - if (!vkutil::load_shader_module(_config.shaderPath.c_str(), _device, &computeShader)) { + if (!vkutil::load_shader_module(_config.shaderPath.c_str(), _device, + &computeShader)) { fmt::println("Error when building the compute shader \n"); return; } - + VkPipelineShaderStageCreateInfo stageInfo{}; stageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stageInfo.pNext = nullptr; stageInfo.stage = VK_SHADER_STAGE_COMPUTE_BIT; stageInfo.module = computeShader; stageInfo.pName = "main"; - + VkComputePipelineCreateInfo computePipelineCreateInfo{}; - computePipelineCreateInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + computePipelineCreateInfo.sType = + VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; computePipelineCreateInfo.pNext = nullptr; computePipelineCreateInfo.layout = _pipelineLayout; computePipelineCreateInfo.stage = stageInfo; - + VK_CHECK(vkCreateComputePipelines(_device, VK_NULL_HANDLE, 1, - &computePipelineCreateInfo, nullptr, - &_pipeline)); - + &computePipelineCreateInfo, nullptr, + &_pipeline)); + if (_config.customSetupCallback) { _config.customSetupCallback(_device, _pipeline, _pipelineLayout); } - + vkDestroyShaderModule(_device, computeShader, nullptr); } @@ -50,12 +53,16 @@ void ComputePipeline::bind(VkCommandBuffer cmd) { vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, _pipeline); } -void ComputePipeline::bindDescriptorSets(VkCommandBuffer cmd, const VkDescriptorSet* descriptorSets, uint32_t setCount) { - vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, _pipelineLayout, - 0, setCount, descriptorSets, 0, nullptr); +void ComputePipeline::bindDescriptorSets(VkCommandBuffer cmd, + const VkDescriptorSet* descriptorSets, + uint32_t setCount) { + vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, + _pipelineLayout, 0, setCount, descriptorSets, 0, + nullptr); } -void ComputePipeline::dispatch(VkCommandBuffer cmd, uint32_t x, uint32_t y, uint32_t z) { +void ComputePipeline::dispatch(VkCommandBuffer cmd, uint32_t x, uint32_t y, + uint32_t z) { vkCmdDispatch(cmd, x, y, z); } diff --git a/src/graphics/vulkan/GraphicsPipeline.cpp b/src/graphics/vulkan/GraphicsPipeline.cpp index 64de2965..c632e5ba 100644 --- a/src/graphics/vulkan/GraphicsPipeline.cpp +++ b/src/graphics/vulkan/GraphicsPipeline.cpp @@ -1,68 +1,73 @@ #include "graphics/vulkan/GraphicsPipeline.h" -GraphicsPipeline::GraphicsPipeline(const GraphicsPipelineConfig& config) - : _config(config) { -} +GraphicsPipeline::GraphicsPipeline(const GraphicsPipelineConfig& config) + : _config(config) {} void GraphicsPipeline::init(VkDevice device) { _device = device; - - VkPipelineLayoutCreateInfo layoutInfo = vkinit::pipeline_layout_create_info(); - + + VkPipelineLayoutCreateInfo layoutInfo = + vkinit::pipeline_layout_create_info(); + if (!_config.descriptorSetLayouts.empty()) { - layoutInfo.setLayoutCount = static_cast(_config.descriptorSetLayouts.size()); + layoutInfo.setLayoutCount = + static_cast(_config.descriptorSetLayouts.size()); layoutInfo.pSetLayouts = _config.descriptorSetLayouts.data(); } - + if (!_config.pushConstants.empty()) { - layoutInfo.pushConstantRangeCount = static_cast(_config.pushConstants.size()); + layoutInfo.pushConstantRangeCount = + static_cast(_config.pushConstants.size()); layoutInfo.pPushConstantRanges = _config.pushConstants.data(); } - - VK_CHECK(vkCreatePipelineLayout(device, &layoutInfo, nullptr, &_pipelineLayout)); - + + VK_CHECK(vkCreatePipelineLayout(device, &layoutInfo, nullptr, + &_pipelineLayout)); + VkShaderModule vertexShader; - if (!vkutil::load_shader_module(_config.vertexShaderPath.c_str(), _device, &vertexShader)) { + if (!vkutil::load_shader_module(_config.vertexShaderPath.c_str(), _device, + &vertexShader)) { fmt::println("Error when building the vertex shader"); return; } - + VkShaderModule fragmentShader; - if (!vkutil::load_shader_module(_config.fragmentShaderPath.c_str(), _device, &fragmentShader)) { + if (!vkutil::load_shader_module(_config.fragmentShaderPath.c_str(), _device, + &fragmentShader)) { fmt::println("Error when building the fragment shader"); vkDestroyShaderModule(_device, vertexShader, nullptr); return; } - + PipelineBuilder pipelineBuilder; pipelineBuilder.set_shaders(vertexShader, fragmentShader); pipelineBuilder.set_input_topology(_config.topology); pipelineBuilder.set_polygon_mode(VK_POLYGON_MODE_FILL); pipelineBuilder.set_cull_mode(_config.cullMode, VK_FRONT_FACE_CLOCKWISE); pipelineBuilder.set_multisampling_none(); - + if (_config.blending) { pipelineBuilder.enable_blending_additive(); } else { pipelineBuilder.disable_blending(); } - + if (_config.depthTest) { pipelineBuilder.enable_depthtest(true, _config.depthCompareOp); } else { pipelineBuilder.disable_depthtest(); } - + pipelineBuilder.set_color_attachment_format(_config.colorFormat); pipelineBuilder.set_depth_format(_config.depthFormat); pipelineBuilder._pipelineLayout = _pipelineLayout; - + if (_config.customPipelineSetup) { _config.customPipelineSetup(pipelineBuilder); } - + _pipeline = pipelineBuilder.build_pipeline(_device); - + vkDestroyShaderModule(_device, vertexShader, nullptr); vkDestroyShaderModule(_device, fragmentShader, nullptr); } @@ -75,12 +80,15 @@ void GraphicsPipeline::bindDescriptorSets(VkCommandBuffer cmd, const VkDescriptorSet* descriptorSets, uint32_t setCount, uint32_t firstSet) { - vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, _pipelineLayout, - firstSet, setCount, descriptorSets, 0, nullptr); + vkCmdBindDescriptorSets(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + _pipelineLayout, firstSet, setCount, descriptorSets, + 0, nullptr); } -void GraphicsPipeline::pushConstants(VkCommandBuffer cmd, VkShaderStageFlags stageFlags, - uint32_t offset, uint32_t size, const void* data) { +void GraphicsPipeline::pushConstants(VkCommandBuffer cmd, + VkShaderStageFlags stageFlags, + uint32_t offset, uint32_t size, + const void* data) { vkCmdPushConstants(cmd, _pipelineLayout, stageFlags, offset, size, data); } diff --git a/src/graphics/vulkan/pipelines.cpp b/src/graphics/vulkan/pipelines.cpp index 5926226b..557d968d 100644 --- a/src/graphics/vulkan/pipelines.cpp +++ b/src/graphics/vulkan/pipelines.cpp @@ -1,4 +1,5 @@ #include "graphics/vulkan/pipelines.h" + #include "graphics/vulkan/vk_engine.h" void GLTFMetallic_Roughness::build_pipelines(VulkanEngine* engine) { @@ -78,7 +79,8 @@ void GLTFMetallic_Roughness::build_opaque_pipeline(VulkanEngine* engine, pipelineBuilder.set_multisampling_none(); pipelineBuilder.disable_blending(); pipelineBuilder.enable_depthtest(true, VK_COMPARE_OP_GREATER_OR_EQUAL); - pipelineBuilder.set_color_attachment_format(engine->_drawImage->get().imageFormat); + pipelineBuilder.set_color_attachment_format( + engine->_drawImage->get().imageFormat); pipelineBuilder.set_depth_format(engine->_depthImage->get().imageFormat); pipelineBuilder._pipelineLayout = layout; @@ -156,7 +158,7 @@ void Pipelines::init(VkDevice device, trianglePipeline = std::make_unique(triangleConfig); trianglePipeline->init(device); - + // Mesh pipeline config GraphicsPipeline::GraphicsPipelineConfig meshConfig; meshConfig.vertexShaderPath = "./shaders/colored_triangle_mesh.vert.spv"; @@ -167,30 +169,30 @@ void Pipelines::init(VkDevice device, meshConfig.depthCompareOp = VK_COMPARE_OP_GREATER; meshConfig.cullMode = VK_CULL_MODE_NONE; meshConfig.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - - // Explicitly setup pipeline details via callback + + // Explicitly setup pipeline details via callback meshConfig.customPipelineSetup = [](PipelineBuilder& builder) { builder.enable_depthtest(true, VK_COMPARE_OP_GREATER); builder.set_multisampling_none(); builder.set_polygon_mode(VK_POLYGON_MODE_FILL); }; - + VkPushConstantRange bufferRange{}; bufferRange.offset = 0; bufferRange.size = sizeof(GPUDrawPushConstants); bufferRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; meshConfig.pushConstants.push_back(bufferRange); - + meshConfig.descriptorSetLayouts.push_back(_singleImageDescriptorLayout); meshPipeline = std::make_unique(meshConfig); meshPipeline->init(device); - + // Compute pipeline ComputePipeline::ComputePipelineConfig gradientConfig; gradientConfig.descriptorSetLayout = _drawImageDescriptorLayout; gradientConfig.shaderPath = "./shaders/gradient.comp.spv"; - + gradientPipeline = std::make_unique(gradientConfig); gradientPipeline->init(device); @@ -201,11 +203,11 @@ void Pipelines::destroy() { if (trianglePipeline) { trianglePipeline->destroy(); } - + if (meshPipeline) { meshPipeline->destroy(); } - + if (gradientPipeline) { gradientPipeline->destroy(); } diff --git a/src/graphics/vulkan/vk_command_buffers.cpp b/src/graphics/vulkan/vk_command_buffers.cpp index 9114b9ed..3547b0c0 100644 --- a/src/graphics/vulkan/vk_command_buffers.cpp +++ b/src/graphics/vulkan/vk_command_buffers.cpp @@ -1,4 +1,5 @@ #include "graphics/vulkan/vk_command_buffers.h" + #include "graphics/vulkan/vk_engine.h" #include "graphics/vulkan/vk_initializers.h" @@ -14,14 +15,15 @@ void CommandBuffers::init_commands(VulkanEngine* vk_engine) { for (auto& _frame : vk_engine->command_buffers_container._frames) { VkCommandPool commandPool; VK_CHECK(vkCreateCommandPool(vk_engine->_device, &commandPoolInfo, - nullptr, - &commandPool)); + nullptr, &commandPool)); - _frame._commandPool = std::make_unique(vk_engine->_device, commandPool); + _frame._commandPool = std::make_unique( + vk_engine->_device, commandPool); // allocate the default command buffer that we will use for rendering VkCommandBufferAllocateInfo cmdAllocInfo = - vkinit::command_buffer_allocate_info(_frame._commandPool->get(), 1); + vkinit::command_buffer_allocate_info(_frame._commandPool->get(), + 1); VK_CHECK(vkAllocateCommandBuffers(vk_engine->_device, &cmdAllocInfo, &_frame._mainCommandBuffer)); @@ -31,25 +33,35 @@ void CommandBuffers::init_commands(VulkanEngine* vk_engine) { VK_CHECK(vkCreateCommandPool(vk_engine->_device, &commandPoolInfo, nullptr, &immCommandPool)); - vk_engine->command_buffers_container._immCommandPool = std::make_unique(vk_engine->_device, immCommandPool); + vk_engine->command_buffers_container._immCommandPool = + std::make_unique(vk_engine->_device, + immCommandPool); // allocate the command buffer for immediate submits const VkCommandBufferAllocateInfo cmdAllocInfo = - vkinit::command_buffer_allocate_info(vk_engine->command_buffers_container._immCommandPool->get(), 1); + vkinit::command_buffer_allocate_info( + vk_engine->command_buffers_container._immCommandPool->get(), + 1); - VK_CHECK(vkAllocateCommandBuffers(vk_engine->_device, &cmdAllocInfo, - &(vk_engine->command_buffers_container._immCommandBuffer))); + VK_CHECK(vkAllocateCommandBuffers( + vk_engine->_device, &cmdAllocInfo, + &(vk_engine->command_buffers_container._immCommandBuffer))); - // Smart pointer will automatically handle cleanup - no need for deletion queue + // Smart pointer will automatically handle cleanup - no need for deletion + // queue } void CommandBuffers::immediate_submit( std::function&& function, VulkanEngine* vk_engine) const { - VK_CHECK(vkResetFences(vk_engine->_device, 1, vk_engine->command_buffers_container._immFence->getPtr())); - VK_CHECK(vkResetCommandBuffer(vk_engine->command_buffers_container._immCommandBuffer, 0)); + VK_CHECK(vkResetFences( + vk_engine->_device, 1, + vk_engine->command_buffers_container._immFence->getPtr())); + VK_CHECK(vkResetCommandBuffer( + vk_engine->command_buffers_container._immCommandBuffer, 0)); - const VkCommandBuffer cmd = vk_engine->command_buffers_container._immCommandBuffer; + const VkCommandBuffer cmd = + vk_engine->command_buffers_container._immCommandBuffer; const VkCommandBufferBeginInfo cmdBeginInfo = vkinit::command_buffer_begin_info( @@ -68,9 +80,12 @@ void CommandBuffers::immediate_submit( // submit command buffer to the queue and execute it. // _renderFence will now block until the graphic commands finish execution - VK_CHECK(vkQueueSubmit2(vk_engine->_graphicsQueue, 1, &submit, - vk_engine->command_buffers_container._immFence->get())); - - VK_CHECK(vkWaitForFences(vk_engine->_device, 1, vk_engine->command_buffers_container._immFence->getPtr(), true, - 9999999999)); + VK_CHECK(vkQueueSubmit2( + vk_engine->_graphicsQueue, 1, &submit, + vk_engine->command_buffers_container._immFence->get())); + + VK_CHECK(vkWaitForFences( + vk_engine->_device, 1, + vk_engine->command_buffers_container._immFence->getPtr(), true, + 9999999999)); } diff --git a/src/graphics/vulkan/vk_command_buffers_container.cpp b/src/graphics/vulkan/vk_command_buffers_container.cpp index c1abcc6c..2c494955 100644 --- a/src/graphics/vulkan/vk_command_buffers_container.cpp +++ b/src/graphics/vulkan/vk_command_buffers_container.cpp @@ -1,9 +1,11 @@ #include "graphics/vulkan/vk_command_buffers_container.h" + #include "graphics/vulkan/vk_engine.h" #include "graphics/vulkan/vk_initializers.h" CommandBuffersContainer::CommandBuffersContainer() { - // Initialize members - actual initialization happens in init_sync_structures + // Initialize members - actual initialization happens in + // init_sync_structures _immCommandBuffer = VK_NULL_HANDLE; } @@ -15,18 +17,25 @@ void CommandBuffersContainer::init_sync_structures(VulkanEngine* vk_engine) { for (auto& _frame : _frames) { VkFence renderFence; - VK_CHECK(vkCreateFence(vk_engine->_device, &fenceCreateInfo, nullptr, &renderFence)); - _frame._renderFence = std::make_unique(vk_engine->_device, renderFence); + VK_CHECK(vkCreateFence(vk_engine->_device, &fenceCreateInfo, nullptr, + &renderFence)); + _frame._renderFence = + std::make_unique(vk_engine->_device, renderFence); VkSemaphore swapchainSemaphore, renderSemaphore; - VK_CHECK(vkCreateSemaphore(vk_engine->_device, &semaphoreCreateInfo, nullptr, &swapchainSemaphore)); - VK_CHECK(vkCreateSemaphore(vk_engine->_device, &semaphoreCreateInfo, nullptr, &renderSemaphore)); - - _frame._swapchainSemaphore = std::make_unique(vk_engine->_device, swapchainSemaphore); - _frame._renderSemaphore = std::make_unique(vk_engine->_device, renderSemaphore); + VK_CHECK(vkCreateSemaphore(vk_engine->_device, &semaphoreCreateInfo, + nullptr, &swapchainSemaphore)); + VK_CHECK(vkCreateSemaphore(vk_engine->_device, &semaphoreCreateInfo, + nullptr, &renderSemaphore)); + + _frame._swapchainSemaphore = std::make_unique( + vk_engine->_device, swapchainSemaphore); + _frame._renderSemaphore = std::make_unique( + vk_engine->_device, renderSemaphore); } VkFence immFence; - VK_CHECK(vkCreateFence(vk_engine->_device, &fenceCreateInfo, nullptr, &immFence)); + VK_CHECK(vkCreateFence(vk_engine->_device, &fenceCreateInfo, nullptr, + &immFence)); _immFence = std::make_unique(vk_engine->_device, immFence); } \ No newline at end of file diff --git a/src/graphics/vulkan/vk_engine.cpp b/src/graphics/vulkan/vk_engine.cpp index 99b94292..edd3e19d 100644 --- a/src/graphics/vulkan/vk_engine.cpp +++ b/src/graphics/vulkan/vk_engine.cpp @@ -30,12 +30,12 @@ #define GLM_ENABLE_EXPERIMENTAL #include +#include "graphics/vulkan/vk_command_buffers.h" #include "graphics/vulkan/vk_images.h" #include "graphics/vulkan/vk_initializers.h" #include "graphics/vulkan/vk_loader.h" #include "graphics/vulkan/vk_pipelines.h" #include "graphics/vulkan/vk_types.h" -#include "graphics/vulkan/vk_command_buffers.h" VulkanEngine* loadedEngine = nullptr; @@ -122,19 +122,25 @@ void VulkanEngine::init_default_data() { // 3 default textures, white, grey, black. 1 pixel each const uint32_t white = glm::packUnorm4x8(glm::vec4(1, 1, 1, 1)); - AllocatedImage whiteImageData = create_image(&white, VkExtent3D{1, 1, 1}, VK_FORMAT_R8G8B8A8_UNORM, + AllocatedImage whiteImageData = + create_image(&white, VkExtent3D{1, 1, 1}, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); - _whiteImage = std::make_unique(_allocator, _device, whiteImageData); + _whiteImage = + std::make_unique(_allocator, _device, whiteImageData); const uint32_t grey = glm::packUnorm4x8(glm::vec4(0.66f, 0.66f, 0.66f, 1)); - AllocatedImage greyImageData = create_image(&grey, VkExtent3D{1, 1, 1}, VK_FORMAT_R8G8B8A8_UNORM, + AllocatedImage greyImageData = + create_image(&grey, VkExtent3D{1, 1, 1}, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); - _greyImage = std::make_unique(_allocator, _device, greyImageData); + _greyImage = + std::make_unique(_allocator, _device, greyImageData); const uint32_t black = glm::packUnorm4x8(glm::vec4(0, 0, 0, 0)); - AllocatedImage blackImageData = create_image(&black, VkExtent3D{1, 1, 1}, VK_FORMAT_R8G8B8A8_UNORM, + AllocatedImage blackImageData = + create_image(&black, VkExtent3D{1, 1, 1}, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); - _blackImage = std::make_unique(_allocator, _device, blackImageData); + _blackImage = + std::make_unique(_allocator, _device, blackImageData); // checkerboard image const uint32_t magenta = glm::packUnorm4x8(glm::vec4(1, 0, 1, 1)); @@ -144,9 +150,11 @@ void VulkanEngine::init_default_data() { pixels[y * 16 + x] = ((x % 2) ^ (y % 2)) ? magenta : black; } } - AllocatedImage errorImageData = create_image(pixels.data(), VkExtent3D{16, 16, 1}, + AllocatedImage errorImageData = + create_image(pixels.data(), VkExtent3D{16, 16, 1}, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT); - _errorCheckerboardImage = std::make_unique(_allocator, _device, errorImageData); + _errorCheckerboardImage = + std::make_unique(_allocator, _device, errorImageData); VkSamplerCreateInfo sampl = {.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO}; @@ -180,7 +188,8 @@ void VulkanEngine::init_default_data() { sceneUniformData->metal_rough_factors = glm::vec4{1, 0.5, 0, 0}; // Store material constants buffer in managed buffers for automatic cleanup - _managedBuffers.push_back(std::make_unique(_allocator, materialConstants)); + _managedBuffers.push_back( + std::make_unique(_allocator, materialConstants)); materialResources.dataBuffer = materialConstants.buffer; materialResources.dataBufferOffset = 0; @@ -249,9 +258,9 @@ void VulkanEngine::init_imgui() { ImGui_ImplVulkan_CreateFontsTexture(); - // Store ImGui cleanup info - will be automatically handled when engine destructs - // Note: ImGui cleanup is now handled by storing the descriptor pool - // that will be automatically destroyed when the device is destroyed + // Store ImGui cleanup info - will be automatically handled when engine + // destructs Note: ImGui cleanup is now handled by storing the descriptor + // pool that will be automatically destroyed when the device is destroyed } void VulkanEngine::init_descriptors() { @@ -308,12 +317,14 @@ void VulkanEngine::init_descriptors() { _frame._frameDescriptors = DescriptorAllocatorGrowable{}; _frame._frameDescriptors.init(_device, 1000, frame_sizes); - // No need for deletion queue - frame descriptors will be cleaned up in cleanup() + // No need for deletion queue - frame descriptors will be cleaned up in + // cleanup() } } void VulkanEngine::init_pipelines() { - pipelines.init(_device, _singleImageDescriptorLayout, _drawImageDescriptorLayout, _drawImage->get()); + pipelines.init(_device, _singleImageDescriptorLayout, + _drawImageDescriptorLayout, _drawImage->get()); // Pipeline cleanup is handled automatically by the Pipelines object metalRoughMaterial.build_pipelines(this); } @@ -326,9 +337,9 @@ void VulkanEngine::init(SDL_Window* window) { loadedEngine = this; init_vulkan(); init_swapchain(); - + command_buffers.init_commands(this); - + command_buffers_container.init_sync_structures(this); init_descriptors(); init_pipelines(); @@ -466,7 +477,6 @@ void VulkanEngine::init_vulkan() { // VMA allocator will be destroyed in cleanup() - no need for deletion queue } - void VulkanEngine::create_swapchain(uint32_t width, uint32_t height) { vkb::SwapchainBuilder swapchainBuilder{_chosenGPU, _device, _surface}; @@ -528,56 +538,53 @@ void VulkanEngine::init_swapchain() { drawImageData.imageExtent = drawImageExtent; // allocate and create the image - vmaCreateImage(_allocator, &rimg_info, &rimg_allocinfo, &drawImageData.image, - &drawImageData.allocation, nullptr); + vmaCreateImage(_allocator, &rimg_info, &rimg_allocinfo, + &drawImageData.image, &drawImageData.allocation, nullptr); // build an image-view for the draw image to use for rendering const VkImageViewCreateInfo rview_info = vkinit::imageview_create_info( - drawImageFormat, drawImageData.image, - VK_IMAGE_ASPECT_COLOR_BIT); + drawImageFormat, drawImageData.image, VK_IMAGE_ASPECT_COLOR_BIT); VK_CHECK(vkCreateImageView(_device, &rview_info, nullptr, &drawImageData.imageView)); // Create smart pointer for automatic cleanup - _drawImage = std::make_unique(_allocator, _device, drawImageData); + _drawImage = + std::make_unique(_allocator, _device, drawImageData); // Create depth image - VkExtent3D depthImageExtent = { - _windowExtent.width, - _windowExtent.height, - 1 - }; + VkExtent3D depthImageExtent = {_windowExtent.width, _windowExtent.height, + 1}; VkFormat depthFormat = VK_FORMAT_D32_SFLOAT; VkImageCreateInfo dimg_info = vkinit::image_create_info( - depthFormat, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - depthImageExtent); + depthFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + depthImageExtent); VmaAllocationCreateInfo dimg_allocinfo = {}; dimg_allocinfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; dimg_allocinfo.requiredFlags = static_cast( - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); AllocatedImage depthImageData{}; depthImageData.imageFormat = depthFormat; depthImageData.imageExtent = depthImageExtent; // allocate and create the depth image - vmaCreateImage(_allocator, &dimg_info, &dimg_allocinfo, &depthImageData.image, - &depthImageData.allocation, nullptr); + vmaCreateImage(_allocator, &dimg_info, &dimg_allocinfo, + &depthImageData.image, &depthImageData.allocation, nullptr); // build an image-view for the depth image VkImageViewCreateInfo dview_info = vkinit::imageview_create_info( - depthFormat, depthImageData.image, VK_IMAGE_ASPECT_DEPTH_BIT); + depthFormat, depthImageData.image, VK_IMAGE_ASPECT_DEPTH_BIT); VK_CHECK(vkCreateImageView(_device, &dview_info, nullptr, &depthImageData.imageView)); // Create smart pointer for automatic cleanup - _depthImage = std::make_unique(_allocator, _device, depthImageData); + _depthImage = + std::make_unique(_allocator, _device, depthImageData); } void VulkanEngine::destroy_swapchain() { @@ -602,7 +609,8 @@ void VulkanEngine::cleanup() { // Smart pointers automatically clean up sync objects // Manual cleanup only for command pools and command buffers if (_frame._commandPool) { - vkDestroyCommandPool(_device, _frame._commandPool->get(), nullptr); + vkDestroyCommandPool(_device, _frame._commandPool->get(), + nullptr); } // Destroy frame descriptors manually @@ -692,28 +700,31 @@ GPUMeshBuffers VulkanEngine::uploadMesh(std::span indices, // copy index buffer memcpy((char*)data + vertexBufferSize, indices.data(), indexBufferSize); - command_buffers.immediate_submit([&](VkCommandBuffer cmd) { - VkBufferCopy vertexCopy{0}; - vertexCopy.dstOffset = 0; - vertexCopy.srcOffset = 0; - vertexCopy.size = vertexBufferSize; + command_buffers.immediate_submit( + [&](VkCommandBuffer cmd) { + VkBufferCopy vertexCopy{0}; + vertexCopy.dstOffset = 0; + vertexCopy.srcOffset = 0; + vertexCopy.size = vertexBufferSize; - vkCmdCopyBuffer(cmd, staging.buffer, newSurface.vertexBuffer.buffer, 1, - &vertexCopy); + vkCmdCopyBuffer(cmd, staging.buffer, + newSurface.vertexBuffer.buffer, 1, &vertexCopy); - VkBufferCopy indexCopy{0}; - indexCopy.dstOffset = 0; - indexCopy.srcOffset = vertexBufferSize; - indexCopy.size = indexBufferSize; + VkBufferCopy indexCopy{0}; + indexCopy.dstOffset = 0; + indexCopy.srcOffset = vertexBufferSize; + indexCopy.size = indexBufferSize; - vkCmdCopyBuffer(cmd, staging.buffer, newSurface.indexBuffer.buffer, 1, - &indexCopy); + vkCmdCopyBuffer(cmd, staging.buffer, + newSurface.indexBuffer.buffer, 1, &indexCopy); }, this); // Store mesh buffers in managed collections for automatic cleanup - _managedBuffers.push_back(std::make_unique(_allocator, newSurface.vertexBuffer)); - _managedBuffers.push_back(std::make_unique(_allocator, newSurface.indexBuffer)); + _managedBuffers.push_back(std::make_unique( + _allocator, newSurface.vertexBuffer)); + _managedBuffers.push_back( + std::make_unique(_allocator, newSurface.indexBuffer)); destroy_buffer(staging); return newSurface; @@ -725,13 +736,13 @@ void VulkanEngine::draw_background(VkCommandBuffer cmd) const { pipelines.gradientPipeline->bind(cmd); // bind descriptor sets - pipelines.gradientPipeline->bindDescriptorSets(cmd, &_drawImageDescriptors, 1); + pipelines.gradientPipeline->bindDescriptorSets(cmd, &_drawImageDescriptors, + 1); // dispatch the compute shader - pipelines.gradientPipeline->dispatch(cmd, - static_cast(std::ceil(_drawExtent.width / 16.0)), - static_cast(std::ceil(_drawExtent.height / 16.0)), - 1); + pipelines.gradientPipeline->dispatch( + cmd, static_cast(std::ceil(_drawExtent.width / 16.0)), + static_cast(std::ceil(_drawExtent.height / 16.0)), 1); } void VulkanEngine::draw_imgui(VkCommandBuffer cmd, @@ -756,7 +767,7 @@ void VulkanEngine::draw_geometry(VkCommandBuffer cmd) { // add it to the current frame's managed buffers for automatic cleanup get_current_frame()._frameBuffers.push_back( - std::make_unique(_allocator, gpuSceneDataBuffer)); + std::make_unique(_allocator, gpuSceneDataBuffer)); // write the buffer auto* sceneUniformData = @@ -844,21 +855,23 @@ void VulkanEngine::draw() { // wait until the gpu has finished rendering the last frame. Timeout of 1 // second - VK_CHECK(vkWaitForFences(_device, 1, get_current_frame()._renderFence->getPtr(), - true, 1000000000)); + VK_CHECK(vkWaitForFences(_device, 1, + get_current_frame()._renderFence->getPtr(), true, + 1000000000)); // Clear frame buffers instead of flushing deletion queue get_current_frame()._frameBuffers.clear(); get_current_frame()._frameDescriptors.clear_pools(_device); - VK_CHECK(vkResetFences(_device, 1, get_current_frame()._renderFence->getPtr())); + VK_CHECK(vkResetFences(_device, 1, + get_current_frame()._renderFence->getPtr())); // request image from the swapchain uint32_t swapchainImageIndex; - const VkResult e = - vkAcquireNextImageKHR(_device, _swapchain, 1000000000, - get_current_frame()._swapchainSemaphore->get(), - nullptr, &swapchainImageIndex); + const VkResult e = vkAcquireNextImageKHR( + _device, _swapchain, 1000000000, + get_current_frame()._swapchainSemaphore->get(), nullptr, + &swapchainImageIndex); if (e == VK_ERROR_OUT_OF_DATE_KHR) { resize_requested = true; return; @@ -891,7 +904,8 @@ void VulkanEngine::draw() { // transition our main draw image into general layout, so we can write into // it, we will overwrite it all, so we don't care about what was the older // layout - vkutil::transition_image(cmd, _drawImage->image(), VK_IMAGE_LAYOUT_UNDEFINED, + vkutil::transition_image(cmd, _drawImage->image(), + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL); draw_background(cmd); @@ -943,9 +957,9 @@ void VulkanEngine::draw() { const VkSemaphoreSubmitInfo waitInfo = vkinit::semaphore_submit_info( VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR, get_current_frame()._swapchainSemaphore->get()); - const VkSemaphoreSubmitInfo signalInfo = - vkinit::semaphore_submit_info(VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, - get_current_frame()._renderSemaphore->get()); + const VkSemaphoreSubmitInfo signalInfo = vkinit::semaphore_submit_info( + VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT, + get_current_frame()._renderSemaphore->get()); const VkSubmitInfo2 submit = vkinit::submit_info(&cmdinfo, &signalInfo, &waitInfo); @@ -966,7 +980,8 @@ void VulkanEngine::draw() { presentInfo.pSwapchains = &_swapchain; presentInfo.swapchainCount = 1; - presentInfo.pWaitSemaphores = get_current_frame()._renderSemaphore->getPtr(); + presentInfo.pWaitSemaphores = + get_current_frame()._renderSemaphore->getPtr(); presentInfo.waitSemaphoreCount = 1; presentInfo.pImageIndices = &swapchainImageIndex; @@ -1062,30 +1077,33 @@ AllocatedImage VulkanEngine::create_image(const void* data, VkExtent3D size, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, mipmapped); - command_buffers.immediate_submit([&](VkCommandBuffer cmd) { - vkutil::transition_image(cmd, new_image.image, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - - VkBufferImageCopy copyRegion = {}; - copyRegion.bufferOffset = 0; - copyRegion.bufferRowLength = 0; - copyRegion.bufferImageHeight = 0; - - copyRegion.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - copyRegion.imageSubresource.mipLevel = 0; - copyRegion.imageSubresource.baseArrayLayer = 0; - copyRegion.imageSubresource.layerCount = 1; - copyRegion.imageExtent = size; - - // copy the buffer into the image - vkCmdCopyBufferToImage(cmd, uploadbuffer.buffer, new_image.image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, - ©Region); - - vkutil::transition_image(cmd, new_image.image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + command_buffers.immediate_submit( + [&](VkCommandBuffer cmd) { + vkutil::transition_image(cmd, new_image.image, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + + VkBufferImageCopy copyRegion = {}; + copyRegion.bufferOffset = 0; + copyRegion.bufferRowLength = 0; + copyRegion.bufferImageHeight = 0; + + copyRegion.imageSubresource.aspectMask = + VK_IMAGE_ASPECT_COLOR_BIT; + copyRegion.imageSubresource.mipLevel = 0; + copyRegion.imageSubresource.baseArrayLayer = 0; + copyRegion.imageSubresource.layerCount = 1; + copyRegion.imageExtent = size; + + // copy the buffer into the image + vkCmdCopyBufferToImage( + cmd, uploadbuffer.buffer, new_image.image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ©Region); + + vkutil::transition_image( + cmd, new_image.image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); }, (VulkanEngine*)this); diff --git a/src/graphics/vulkan/vk_loader.cpp b/src/graphics/vulkan/vk_loader.cpp index 5c00e7be..5989c425 100644 --- a/src/graphics/vulkan/vk_loader.cpp +++ b/src/graphics/vulkan/vk_loader.cpp @@ -69,8 +69,7 @@ std::optional>> loadGltfMeshes( if (asset) { gltf = std::move(asset.get()); } else { - LOGE("Failed to load glTF: {}", - fastgltf::to_underlying(asset.error())); + LOGE("Failed to load glTF: {}", fastgltf::to_underlying(asset.error())); return {}; } @@ -207,7 +206,8 @@ VkSamplerMipmapMode extract_mipmap_mode(fastgltf::Filter filter) { std::optional> loadGltf(VulkanEngine* engine, std::string_view filePath) { - LOGI("Loading GLTF: {}", filePath);if (!std::filesystem::exists(filePath)) { + LOGI("Loading GLTF: {}", filePath); + if (!std::filesystem::exists(filePath)) { LOGW("File does not exist: {}", filePath); } auto scene = std::make_shared(); @@ -228,7 +228,8 @@ std::optional> loadGltf(VulkanEngine* engine, if (load) { gltf = std::move(load.get()); } else { - LOGE("Failed to load glTF: {} ", fastgltf::to_underlying(load.error())); + LOGE("Failed to load glTF: {} ", + fastgltf::to_underlying(load.error())); return {}; } } else if (type == fastgltf::GltfType::GLB) { @@ -237,7 +238,8 @@ std::optional> loadGltf(VulkanEngine* engine, if (load) { gltf = std::move(load.get()); } else { - LOGE("Failed to load glTF: {} ", fastgltf::to_underlying(load.error())); + LOGE("Failed to load glTF: {} ", + fastgltf::to_underlying(load.error())); return {}; } } else { @@ -350,7 +352,8 @@ std::optional> loadGltf(VulkanEngine* engine, GLTFMetallic_Roughness::MaterialConstants constants = {}; constants.colorFactors = glm::vec4(1.0f); // White base color - constants.metal_rough_factors = glm::vec4(0.0f); // Non-metallic, smooth + constants.metal_rough_factors = + glm::vec4(0.0f); // Non-metallic, smooth sceneMaterialConstants[0] = constants; diff --git a/src/graphics/vulkan/vk_pipelines.cpp b/src/graphics/vulkan/vk_pipelines.cpp index 40438f0b..7d2321d8 100644 --- a/src/graphics/vulkan/vk_pipelines.cpp +++ b/src/graphics/vulkan/vk_pipelines.cpp @@ -1,12 +1,12 @@ #include "graphics/vulkan/vk_pipelines.h" #include +#include #include #include #include -#include "core/Logging.h" -#include +#include "core/Logging.h" #include "graphics/vulkan/vk_initializers.h" bool vkutil::load_shader_module(const char* filePath, VkDevice device, @@ -75,63 +75,61 @@ bool vkutil::load_shader_module(const char* filePath, VkDevice device, void PipelineBuilder::clear() { // Initialize input assembly with proper defaults _inputAssembly = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - .primitiveRestartEnable = VK_FALSE - }; + .sType = + VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + .primitiveRestartEnable = VK_FALSE}; // Initialize rasterizer with proper defaults _rasterizer = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .depthClampEnable = VK_FALSE, - .rasterizerDiscardEnable = VK_FALSE, - .polygonMode = VK_POLYGON_MODE_FILL, - .cullMode = VK_CULL_MODE_NONE, - .frontFace = VK_FRONT_FACE_CLOCKWISE, - .depthBiasEnable = VK_FALSE, - .depthBiasConstantFactor = 0.0f, - .depthBiasClamp = 0.0f, - .depthBiasSlopeFactor = 0.0f, - .lineWidth = 1.0f // CRITICAL: Must be 1.0f, not 0.0f + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .depthClampEnable = VK_FALSE, + .rasterizerDiscardEnable = VK_FALSE, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_NONE, + .frontFace = VK_FRONT_FACE_CLOCKWISE, + .depthBiasEnable = VK_FALSE, + .depthBiasConstantFactor = 0.0f, + .depthBiasClamp = 0.0f, + .depthBiasSlopeFactor = 0.0f, + .lineWidth = 1.0f // CRITICAL: Must be 1.0f, not 0.0f }; // Initialize color blend attachment with defaults - _colorBlendAttachment = { - .blendEnable = VK_FALSE, - .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | - VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT - }; + _colorBlendAttachment = {.blendEnable = VK_FALSE, + .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT}; // Initialize multisampling with proper defaults _multisampling = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT, // CRITICAL: Must be valid sample count - .sampleShadingEnable = VK_FALSE, - .minSampleShading = 1.0f, - .pSampleMask = nullptr, - .alphaToCoverageEnable = VK_FALSE, - .alphaToOneEnable = VK_FALSE - }; + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .rasterizationSamples = + VK_SAMPLE_COUNT_1_BIT, // CRITICAL: Must be valid sample + // count + .sampleShadingEnable = VK_FALSE, + .minSampleShading = 1.0f, + .pSampleMask = nullptr, + .alphaToCoverageEnable = VK_FALSE, + .alphaToOneEnable = VK_FALSE}; _pipelineLayout = {}; // Initialize depth-stencil with proper defaults _depthStencil = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - .depthTestEnable = VK_FALSE, - .depthWriteEnable = VK_FALSE, - .depthCompareOp = VK_COMPARE_OP_LESS, - .depthBoundsTestEnable = VK_FALSE, - .stencilTestEnable = VK_FALSE, - .minDepthBounds = 0.0f, - .maxDepthBounds = 1.0f - }; + .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .depthTestEnable = VK_FALSE, + .depthWriteEnable = VK_FALSE, + .depthCompareOp = VK_COMPARE_OP_LESS, + .depthBoundsTestEnable = VK_FALSE, + .stencilTestEnable = VK_FALSE, + .minDepthBounds = 0.0f, + .maxDepthBounds = 1.0f}; // Initialize rendering info with proper defaults - _renderInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, - .depthAttachmentFormat = VK_FORMAT_UNDEFINED - }; + _renderInfo = {.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + .depthAttachmentFormat = VK_FORMAT_UNDEFINED}; _shaderStages.clear(); } @@ -170,7 +168,8 @@ VkPipeline PipelineBuilder::build_pipeline(VkDevice device) const { viewportState.viewportCount = 1; viewportState.scissorCount = 1; // Use dynamic viewport and scissor - VkDynamicState dynamicStates[] = { VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR }; + VkDynamicState dynamicStates[] = {VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR}; VkPipelineDynamicStateCreateInfo dynamicState = {}; dynamicState.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; dynamicState.pDynamicStates = dynamicStates; @@ -178,7 +177,8 @@ VkPipeline PipelineBuilder::build_pipeline(VkDevice device) const { // setup color blending VkPipelineColorBlendStateCreateInfo colorBlending = {}; - colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; + colorBlending.sType = + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; colorBlending.pNext = nullptr; colorBlending.logicOpEnable = VK_FALSE; colorBlending.logicOp = VK_LOGIC_OP_COPY; @@ -187,8 +187,7 @@ VkPipeline PipelineBuilder::build_pipeline(VkDevice device) const { // completely clear VertexInputStateCreateInfo const VkPipelineVertexInputStateCreateInfo vertexInputInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO - }; + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO}; // build the actual pipeline VkGraphicsPipelineCreateInfo pipelineInfo = {}; @@ -197,22 +196,21 @@ VkPipeline PipelineBuilder::build_pipeline(VkDevice device) const { pipelineInfo.stageCount = static_cast(_shaderStages.size()); pipelineInfo.pStages = _shaderStages.data(); pipelineInfo.pVertexInputState = &vertexInputInfo; - pipelineInfo.pInputAssemblyState = &inputAssembly; // Use our local copy + pipelineInfo.pInputAssemblyState = &inputAssembly; // Use our local copy pipelineInfo.pViewportState = &viewportState; - pipelineInfo.pRasterizationState = &rasterizer; // Use our local copy + pipelineInfo.pRasterizationState = &rasterizer; // Use our local copy pipelineInfo.pMultisampleState = &multisampling; // Use our local copy pipelineInfo.pDepthStencilState = &_depthStencil; pipelineInfo.pColorBlendState = &colorBlending; pipelineInfo.pDynamicState = &dynamicState; pipelineInfo.layout = _pipelineLayout; - pipelineInfo.renderPass = VK_NULL_HANDLE; // We use dynamic rendering + pipelineInfo.renderPass = VK_NULL_HANDLE; // We use dynamic rendering pipelineInfo.subpass = 0; pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; VkPipeline newPipeline; if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &newPipeline) != VK_SUCCESS) { - LOGE("Failed to create graphics pipeline in build_pipeline."); return VK_NULL_HANDLE; } @@ -255,7 +253,8 @@ void PipelineBuilder::set_cull_mode(VkCullModeFlags cullMode, } void PipelineBuilder::set_multisampling_none() { - _multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; + _multisampling.sType = + VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; _multisampling.pNext = nullptr; _multisampling.sampleShadingEnable = VK_FALSE; _multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; @@ -283,8 +282,7 @@ void PipelineBuilder::set_color_attachment_format(VkFormat format) { void PipelineBuilder::set_depth_format(VkFormat format) { // Ensure format is valid or undefined - if (format != VK_FORMAT_D16_UNORM && - format != VK_FORMAT_D32_SFLOAT && + if (format != VK_FORMAT_D16_UNORM && format != VK_FORMAT_D32_SFLOAT && format != VK_FORMAT_D16_UNORM_S8_UINT && format != VK_FORMAT_D24_UNORM_S8_UINT && format != VK_FORMAT_D32_SFLOAT_S8_UINT && diff --git a/src/include/graphics/vulkan/ComputePipeline.h b/src/include/graphics/vulkan/ComputePipeline.h index a88fe15c..951a3597 100644 --- a/src/include/graphics/vulkan/ComputePipeline.h +++ b/src/include/graphics/vulkan/ComputePipeline.h @@ -1,32 +1,41 @@ #pragma once +#include + #include "IPipeline.h" -#include "vk_types.h" #include "vk_initializers.h" #include "vk_pipelines.h" -#include +#include "vk_types.h" class ComputePipeline : public IPipeline { public: struct ComputePipelineConfig { VkDescriptorSetLayout descriptorSetLayout; std::string shaderPath; - std::function customSetupCallback = nullptr; + std::function + customSetupCallback = nullptr; }; ComputePipeline() = default; explicit ComputePipeline(const ComputePipelineConfig& config); - + void init(VkDevice device) override; void bind(VkCommandBuffer cmd) override; void destroy() override; - - VkPipeline getPipeline() const override { return _pipeline; } - VkPipelineLayout getLayout() const override { return _pipelineLayout; } + + VkPipeline getPipeline() const override { + return _pipeline; + } + + VkPipelineLayout getLayout() const override { + return _pipelineLayout; + } // Specific to compute pipelines void dispatch(VkCommandBuffer cmd, uint32_t x, uint32_t y, uint32_t z = 1); - void bindDescriptorSets(VkCommandBuffer cmd, const VkDescriptorSet* descriptorSets, uint32_t setCount); + void bindDescriptorSets(VkCommandBuffer cmd, + const VkDescriptorSet* descriptorSets, + uint32_t setCount); private: VkDevice _device = VK_NULL_HANDLE; diff --git a/src/include/graphics/vulkan/GraphicsPipeline.h b/src/include/graphics/vulkan/GraphicsPipeline.h index 1e9a6f54..bbff378f 100644 --- a/src/include/graphics/vulkan/GraphicsPipeline.h +++ b/src/include/graphics/vulkan/GraphicsPipeline.h @@ -1,13 +1,14 @@ #pragma once -#include "IPipeline.h" -#include "vk_types.h" -#include "vk_initializers.h" -#include "vk_pipelines.h" #include #include #include +#include "IPipeline.h" +#include "vk_initializers.h" +#include "vk_pipelines.h" +#include "vk_types.h" + class GraphicsPipeline : public IPipeline { public: struct GraphicsPipelineConfig { @@ -27,19 +28,25 @@ class GraphicsPipeline : public IPipeline { GraphicsPipeline() = default; explicit GraphicsPipeline(const GraphicsPipelineConfig& config); - + void init(VkDevice device) override; void bind(VkCommandBuffer cmd) override; void destroy() override; - - VkPipeline getPipeline() const override { return _pipeline; } - VkPipelineLayout getLayout() const override { return _pipelineLayout; } + + VkPipeline getPipeline() const override { + return _pipeline; + } + + VkPipelineLayout getLayout() const override { + return _pipelineLayout; + } // Graphics pipeline specific methods void bindDescriptorSets(VkCommandBuffer cmd, const VkDescriptorSet* descriptorSets, uint32_t setCount, uint32_t firstSet = 0); - void pushConstants(VkCommandBuffer cmd, VkShaderStageFlags stageFlags, uint32_t offset, uint32_t size, const void* data); + void pushConstants(VkCommandBuffer cmd, VkShaderStageFlags stageFlags, + uint32_t offset, uint32_t size, const void* data); private: VkDevice _device = VK_NULL_HANDLE; diff --git a/src/include/graphics/vulkan/IPipeline.h b/src/include/graphics/vulkan/IPipeline.h index fb5bddd5..bc24c117 100644 --- a/src/include/graphics/vulkan/IPipeline.h +++ b/src/include/graphics/vulkan/IPipeline.h @@ -5,11 +5,11 @@ class IPipeline { public: virtual ~IPipeline() = default; - + virtual void init(VkDevice device) = 0; virtual void bind(VkCommandBuffer cmd) = 0; virtual void destroy() = 0; - + // Optional methods for pipeline-specific binding virtual VkPipeline getPipeline() const = 0; virtual VkPipelineLayout getLayout() const = 0; diff --git a/src/include/graphics/vulkan/pipelines.h b/src/include/graphics/vulkan/pipelines.h index a9229949..7197970a 100644 --- a/src/include/graphics/vulkan/pipelines.h +++ b/src/include/graphics/vulkan/pipelines.h @@ -2,14 +2,14 @@ #include +#include "ComputePipeline.h" +#include "GraphicsPipeline.h" +#include "IPipeline.h" #include "vk_descriptors.h" #include "vk_images.h" #include "vk_initializers.h" #include "vk_pipelines.h" #include "vk_types.h" -#include "IPipeline.h" -#include "GraphicsPipeline.h" -#include "ComputePipeline.h" class VulkanEngine; diff --git a/src/include/graphics/vulkan/vk_command_buffers.h b/src/include/graphics/vulkan/vk_command_buffers.h index 4ca8a23f..455da186 100644 --- a/src/include/graphics/vulkan/vk_command_buffers.h +++ b/src/include/graphics/vulkan/vk_command_buffers.h @@ -1,20 +1,17 @@ #pragma once - -#include -#include #include +#include +#include class VulkanEngine; class CommandBuffers { public: - void immediate_submit(std::function&& function, VulkanEngine* vk_engine) const; void init_commands(VulkanEngine* vk_engine); private: - }; \ No newline at end of file diff --git a/src/include/graphics/vulkan/vk_command_buffers_container.h b/src/include/graphics/vulkan/vk_command_buffers_container.h index 0cc47880..3a55e5b2 100644 --- a/src/include/graphics/vulkan/vk_command_buffers_container.h +++ b/src/include/graphics/vulkan/vk_command_buffers_container.h @@ -18,7 +18,8 @@ struct FrameData { std::unique_ptr _renderFence; DescriptorAllocatorGrowable _frameDescriptors; - std::vector> _frameBuffers; // For per-frame temporary buffers + std::vector> + _frameBuffers; // For per-frame temporary buffers }; class VulkanEngine; @@ -30,7 +31,7 @@ class CommandBuffersContainer { // Frame management FrameData _frames[FRAME_OVERLAP]; - + FrameData& get_current_frame(unsigned int frameNumber) { return _frames[frameNumber % FRAME_OVERLAP]; } diff --git a/src/include/graphics/vulkan/vk_engine.h b/src/include/graphics/vulkan/vk_engine.h index 40db0c65..bd375cee 100644 --- a/src/include/graphics/vulkan/vk_engine.h +++ b/src/include/graphics/vulkan/vk_engine.h @@ -13,15 +13,13 @@ #include #include -#include "vk_descriptors.h" -#include "vk_types.h" -#include "vk_smart_wrappers.h" - -#include "pipelines.h" #include "ComputePipeline.h" - +#include "pipelines.h" #include "vk_command_buffers.h" #include "vk_command_buffers_container.h" +#include "vk_descriptors.h" +#include "vk_smart_wrappers.h" +#include "vk_types.h" class Camera; class VulkanEngine; @@ -29,7 +27,6 @@ struct DrawContext; struct LoadedGLTF; struct MeshAsset; - struct GPUSceneData { glm::mat4 view; glm::mat4 proj; @@ -64,7 +61,6 @@ struct DrawContext { class VulkanEngine { public: - Pipelines pipelines; CommandBuffers command_buffers; @@ -142,7 +138,6 @@ class VulkanEngine { VkDescriptorSet _drawImageDescriptors; VkDescriptorSetLayout _drawImageDescriptorLayout; - GPUMeshBuffers rectangle; GPUMeshBuffers uploadMesh(std::span indices, diff --git a/src/include/graphics/vulkan/vk_smart_wrappers.h b/src/include/graphics/vulkan/vk_smart_wrappers.h index 568fddf3..d037aabf 100644 --- a/src/include/graphics/vulkan/vk_smart_wrappers.h +++ b/src/include/graphics/vulkan/vk_smart_wrappers.h @@ -1,8 +1,9 @@ #pragma once #include -#include #include +#include + #include "vk_types.h" class VulkanEngine; @@ -10,8 +11,9 @@ class VulkanEngine; // RAII wrapper for VkFence class VulkanFence { public: - VulkanFence(VkDevice device, VkFence fence) : device_(device), fence_(fence) {} - + VulkanFence(VkDevice device, VkFence fence) + : device_(device), fence_(fence) {} + ~VulkanFence() { if (fence_ != VK_NULL_HANDLE) { vkDestroyFence(device_, fence_, nullptr); @@ -19,7 +21,7 @@ class VulkanFence { } // Move constructor and assignment - VulkanFence(VulkanFence&& other) noexcept + VulkanFence(VulkanFence&& other) noexcept : device_(other.device_), fence_(other.fence_) { other.fence_ = VK_NULL_HANDLE; } @@ -40,9 +42,17 @@ class VulkanFence { VulkanFence(const VulkanFence&) = delete; VulkanFence& operator=(const VulkanFence&) = delete; - VkFence get() const { return fence_; } - VkFence* getPtr() { return &fence_; } - operator VkFence() const { return fence_; } + VkFence get() const { + return fence_; + } + + VkFence* getPtr() { + return &fence_; + } + + operator VkFence() const { + return fence_; + } private: VkDevice device_; @@ -52,8 +62,9 @@ class VulkanFence { // RAII wrapper for VkSemaphore class VulkanSemaphore { public: - VulkanSemaphore(VkDevice device, VkSemaphore semaphore) : device_(device), semaphore_(semaphore) {} - + VulkanSemaphore(VkDevice device, VkSemaphore semaphore) + : device_(device), semaphore_(semaphore) {} + ~VulkanSemaphore() { if (semaphore_ != VK_NULL_HANDLE) { vkDestroySemaphore(device_, semaphore_, nullptr); @@ -61,7 +72,7 @@ class VulkanSemaphore { } // Move constructor and assignment - VulkanSemaphore(VulkanSemaphore&& other) noexcept + VulkanSemaphore(VulkanSemaphore&& other) noexcept : device_(other.device_), semaphore_(other.semaphore_) { other.semaphore_ = VK_NULL_HANDLE; } @@ -82,9 +93,17 @@ class VulkanSemaphore { VulkanSemaphore(const VulkanSemaphore&) = delete; VulkanSemaphore& operator=(const VulkanSemaphore&) = delete; - VkSemaphore get() const { return semaphore_; } - VkSemaphore* getPtr() { return &semaphore_; } - operator VkSemaphore() const { return semaphore_; } + VkSemaphore get() const { + return semaphore_; + } + + VkSemaphore* getPtr() { + return &semaphore_; + } + + operator VkSemaphore() const { + return semaphore_; + } private: VkDevice device_; @@ -94,8 +113,9 @@ class VulkanSemaphore { // RAII wrapper for VkCommandPool class VulkanCommandPool { public: - VulkanCommandPool(VkDevice device, VkCommandPool commandPool) : device_(device), commandPool_(commandPool) {} - + VulkanCommandPool(VkDevice device, VkCommandPool commandPool) + : device_(device), commandPool_(commandPool) {} + ~VulkanCommandPool() { if (commandPool_ != VK_NULL_HANDLE) { vkDestroyCommandPool(device_, commandPool_, nullptr); @@ -103,7 +123,7 @@ class VulkanCommandPool { } // Move constructor and assignment - VulkanCommandPool(VulkanCommandPool&& other) noexcept + VulkanCommandPool(VulkanCommandPool&& other) noexcept : device_(other.device_), commandPool_(other.commandPool_) { other.commandPool_ = VK_NULL_HANDLE; } @@ -124,9 +144,17 @@ class VulkanCommandPool { VulkanCommandPool(const VulkanCommandPool&) = delete; VulkanCommandPool& operator=(const VulkanCommandPool&) = delete; - VkCommandPool get() const { return commandPool_; } - VkCommandPool* getPtr() { return &commandPool_; } - operator VkCommandPool() const { return commandPool_; } + VkCommandPool get() const { + return commandPool_; + } + + VkCommandPool* getPtr() { + return &commandPool_; + } + + operator VkCommandPool() const { + return commandPool_; + } private: VkDevice device_; @@ -136,8 +164,9 @@ class VulkanCommandPool { // RAII wrapper for VkImageView class VulkanImageView { public: - VulkanImageView(VkDevice device, VkImageView imageView) : device_(device), imageView_(imageView) {} - + VulkanImageView(VkDevice device, VkImageView imageView) + : device_(device), imageView_(imageView) {} + ~VulkanImageView() { if (imageView_ != VK_NULL_HANDLE) { vkDestroyImageView(device_, imageView_, nullptr); @@ -145,7 +174,7 @@ class VulkanImageView { } // Move constructor and assignment - VulkanImageView(VulkanImageView&& other) noexcept + VulkanImageView(VulkanImageView&& other) noexcept : device_(other.device_), imageView_(other.imageView_) { other.imageView_ = VK_NULL_HANDLE; } @@ -166,9 +195,17 @@ class VulkanImageView { VulkanImageView(const VulkanImageView&) = delete; VulkanImageView& operator=(const VulkanImageView&) = delete; - VkImageView get() const { return imageView_; } - VkImageView* getPtr() { return &imageView_; } - operator VkImageView() const { return imageView_; } + VkImageView get() const { + return imageView_; + } + + VkImageView* getPtr() { + return &imageView_; + } + + operator VkImageView() const { + return imageView_; + } private: VkDevice device_; @@ -178,9 +215,9 @@ class VulkanImageView { // RAII wrapper for AllocatedBuffer class VulkanBuffer { public: - VulkanBuffer(VmaAllocator allocator, const AllocatedBuffer& buffer) + VulkanBuffer(VmaAllocator allocator, const AllocatedBuffer& buffer) : allocator_(allocator), buffer_(buffer) {} - + ~VulkanBuffer() { if (buffer_.buffer != VK_NULL_HANDLE) { vmaDestroyBuffer(allocator_, buffer_.buffer, buffer_.allocation); @@ -188,7 +225,7 @@ class VulkanBuffer { } // Move constructor and assignment - VulkanBuffer(VulkanBuffer&& other) noexcept + VulkanBuffer(VulkanBuffer&& other) noexcept : allocator_(other.allocator_), buffer_(other.buffer_) { other.buffer_.buffer = VK_NULL_HANDLE; other.buffer_.allocation = nullptr; @@ -197,7 +234,8 @@ class VulkanBuffer { VulkanBuffer& operator=(VulkanBuffer&& other) noexcept { if (this != &other) { if (buffer_.buffer != VK_NULL_HANDLE) { - vmaDestroyBuffer(allocator_, buffer_.buffer, buffer_.allocation); + vmaDestroyBuffer(allocator_, buffer_.buffer, + buffer_.allocation); } allocator_ = other.allocator_; buffer_ = other.buffer_; @@ -211,9 +249,17 @@ class VulkanBuffer { VulkanBuffer(const VulkanBuffer&) = delete; VulkanBuffer& operator=(const VulkanBuffer&) = delete; - const AllocatedBuffer& get() const { return buffer_; } - VkBuffer buffer() const { return buffer_.buffer; } - VmaAllocation allocation() const { return buffer_.allocation; } + const AllocatedBuffer& get() const { + return buffer_; + } + + VkBuffer buffer() const { + return buffer_.buffer; + } + + VmaAllocation allocation() const { + return buffer_.allocation; + } private: VmaAllocator allocator_; @@ -223,9 +269,10 @@ class VulkanBuffer { // RAII wrapper for AllocatedImage class VulkanImage { public: - VulkanImage(VmaAllocator allocator, VkDevice device, const AllocatedImage& image) + VulkanImage(VmaAllocator allocator, VkDevice device, + const AllocatedImage& image) : allocator_(allocator), device_(device), image_(image) {} - + ~VulkanImage() { if (image_.imageView != VK_NULL_HANDLE) { vkDestroyImageView(device_, image_.imageView, nullptr); @@ -236,8 +283,10 @@ class VulkanImage { } // Move constructor and assignment - VulkanImage(VulkanImage&& other) noexcept - : allocator_(other.allocator_), device_(other.device_), image_(other.image_) { + VulkanImage(VulkanImage&& other) noexcept + : allocator_(other.allocator_), + device_(other.device_), + image_(other.image_) { other.image_.image = VK_NULL_HANDLE; other.image_.imageView = VK_NULL_HANDLE; other.image_.allocation = nullptr; @@ -265,10 +314,21 @@ class VulkanImage { VulkanImage(const VulkanImage&) = delete; VulkanImage& operator=(const VulkanImage&) = delete; - const AllocatedImage& get() const { return image_; } - VkImage image() const { return image_.image; } - VkImageView imageView() const { return image_.imageView; } - VmaAllocation allocation() const { return image_.allocation; } + const AllocatedImage& get() const { + return image_; + } + + VkImage image() const { + return image_.image; + } + + VkImageView imageView() const { + return image_.imageView; + } + + VmaAllocation allocation() const { + return image_.allocation; + } private: VmaAllocator allocator_; @@ -277,7 +337,7 @@ class VulkanImage { }; // Factory functions for creating smart pointers -template +template std::unique_ptr make_vulkan_unique(Args&&... args) { return std::make_unique(std::forward(args)...); } From 720cab55d9b4b6cbc77190ae49aae42a61011aab Mon Sep 17 00:00:00 2001 From: Nikita Zuev Dmitrievich <44869886+reeegry@users.noreply.github.com> Date: Mon, 29 Sep 2025 15:48:52 +0300 Subject: [PATCH 3/3] remove workflow_dispatch: from codestyle.yml --- .github/workflows/codestyle.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml index 3586e6e5..a03b3440 100644 --- a/.github/workflows/codestyle.yml +++ b/.github/workflows/codestyle.yml @@ -14,7 +14,6 @@ on: - cmake/** - scripts/** - shaders/** - workflow_dispatch: jobs: cpp-linter: