
.. _program_listing_file_Src_GraphicsEngineVulkan_vulkan_base_PipelineBuilder.ixx:

Program Listing for File PipelineBuilder.ixx
============================================

|exhale_lsh| :ref:`Return to documentation for file <file_Src_GraphicsEngineVulkan_vulkan_base_PipelineBuilder.ixx>` (``Src/GraphicsEngineVulkan/vulkan_base/PipelineBuilder.ixx``)

.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS

.. code-block:: cpp

   module;
   #include <cstdint>
   
   #include <span>
   #include <vector>
   #include <vulkan/vulkan.hpp>
   
   export module kataglyphis.vulkan.pipeline_builder;
   
   export namespace Kataglyphis {
   
   // The device-free half of PipelineBuilder::build: every sub-state a
   // vk::GraphicsPipelineCreateInfo points at, assembled without touching a
   // vk::Device. Freely movable - dynamic_states/color_states are owned here,
   // and moving a std::vector never reallocates its buffer, so the pointers
   // dynamic_state_create_info.pDynamicStates and color_blending.pAttachments
   // stay valid across the move out of PipelineBuilder::buildState().
   struct GraphicsPipelineState
   {
       vk::PipelineVertexInputStateCreateInfo vertex_input_create_info;
       vk::PipelineInputAssemblyStateCreateInfo input_assembly;
       vk::PipelineViewportStateCreateInfo viewport_state_create_info;
       std::vector<vk::DynamicState> dynamic_states;
       vk::PipelineDynamicStateCreateInfo dynamic_state_create_info;
       vk::PipelineRasterizationStateCreateInfo rasterizer_create_info;
       vk::PipelineMultisampleStateCreateInfo multisample_create_info;
       vk::PipelineDepthStencilStateCreateInfo depth_stencil_create_info;
       std::vector<vk::PipelineColorBlendAttachmentState> color_states;
       vk::PipelineColorBlendStateCreateInfo color_blending;
       bool use_color_blend_state = true;
   };
   
   // Wires the shader stages, pipeline layout, render pass and subpass onto a
   // GraphicsPipelineState and returns the top-level create-info ready for
   // vk::Device::createGraphicsPipelines. Borrows into both state and stages -
   // both must outlive the createGraphicsPipelines call that consumes the
   // returned value, the same lifetime rule PipelineLayoutHelper.hpp documents.
   [[nodiscard]] vk::GraphicsPipelineCreateInfo linkGraphicsPipelineCreateInfo(const GraphicsPipelineState &state,
     std::span<const vk::PipelineShaderStageCreateInfo> stages,
     vk::PipelineLayout layout,
     vk::RenderPass render_pass,
     uint32_t subpass);
   
   // Fluent builder for the graphics pipeline construction that was previously
   // copy-pasted across the render stages. Defaults match the most common
   // variant: triangle list, dynamic viewport/scissor, fill mode, back-face
   // culling, counter-clockwise front face, no blending on a single color
   // attachment, depth test + write with CompareOp::eLess, single sample.
   // Pipeline LAYOUT creation stays in the stages; this builder only builds
   // the vk::Pipeline.
   class PipelineBuilder
   {
     public:
       PipelineBuilder();
   
       PipelineBuilder &setShaderStages(std::vector<vk::PipelineShaderStageCreateInfo> shader_stages);
       PipelineBuilder &setVertexInput(std::vector<vk::VertexInputBindingDescription> bindings,
         std::vector<vk::VertexInputAttributeDescription> attributes);
       PipelineBuilder &setCullMode(vk::CullModeFlags cull_mode);
       // When enabled uses the standard alpha blending factors
       // (srcAlpha/oneMinusSrcAlpha for color, one/zero for alpha, both eAdd).
       PipelineBuilder &setAlphaBlending(bool enable);
       PipelineBuilder &setColorAttachmentCount(uint32_t count);
       // Pass false for depth-only pipelines (no pColorBlendState at all).
       PipelineBuilder &setUseColorBlendState(bool use_color_blend_state);
       PipelineBuilder &setDepthTest(bool enable);
       PipelineBuilder &setDepthWrite(bool enable);
       PipelineBuilder &setDepthCompareOp(vk::CompareOp compare_op);
       // Depth clamp ("shadow pancaking"): fragments nearer than the near plane
       // clamp to depth 0 instead of being CLIPPED. Only legal when the device
       // feature is enabled - pass VulkanDevice::supportsDepthClamp().
       PipelineBuilder &setDepthClamp(bool enable);
       // Adds VK_DYNAMIC_STATE_CULL_MODE so the cull mode set by setCullMode becomes
       // a per-draw dynamic state (vkCmdSetCullMode). Core in Vulkan 1.3, which the
       // engine targets. Opt-in: off by default, so every other pipeline keeps its
       // static cull mode and needs no per-draw setCullMode. Used by the forward
       // raster pass to disable back-face culling for doubleSided glTF meshes only.
       PipelineBuilder &setDynamicCullMode(bool enable);
   
       // Assembles every sub-state build() needs without touching a vk::Device -
       // see GraphicsPipelineState. Pair with linkGraphicsPipelineCreateInfo to
       // reproduce build()'s result one call site at a time in a CPU-only test.
       [[nodiscard]] GraphicsPipelineState buildState() const;
   
       // Creates the pipeline via createGraphicsPipelines(pipeline_cache, ...);
       // aborts through ASSERT_VULKAN with error_message on failure.
       // pipeline_cache may be null (no caching).
       [[nodiscard]] vk::Pipeline build(vk::Device device,
         vk::PipelineLayout pipeline_layout,
         vk::RenderPass render_pass,
         vk::PipelineCache pipeline_cache = nullptr,
         uint32_t subpass = 0,
         const char *error_message = "Failed to create a graphics pipeline!") const;
   
     private:
       std::vector<vk::PipelineShaderStageCreateInfo> shader_stages;
       std::vector<vk::VertexInputBindingDescription> vertex_bindings;
       std::vector<vk::VertexInputAttributeDescription> vertex_attributes;
       // No setter and never varies - CascadedShadowMap.cpp reasons about this
       // exact default explicitly (culling is disabled there instead of flipping
       // the front face to match the projection's Y-flip).
       static constexpr vk::FrontFace kFrontFace = vk::FrontFace::eCounterClockwise;
   
       vk::CullModeFlags cull_mode = vk::CullModeFlagBits::eBack;
       bool alpha_blending = false;
       uint32_t color_attachment_count = 1;
       bool use_color_blend_state = true;
       bool depth_test = true;
       bool depth_write = true;
       vk::CompareOp depth_compare_op = vk::CompareOp::eLess;
       bool depth_clamp = false;
       bool dynamic_cull_mode = false;
   };
   }// namespace Kataglyphis
