#pragma once #include #include #include namespace wowee { namespace rendering { // Builder pattern for VkGraphicsPipeline creation. // Usage: // auto pipeline = PipelineBuilder() // .setShaders(vertStage, fragStage) // .setVertexInput(bindings, attributes) // .setTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) // .setRasterization(VK_POLYGON_MODE_FILL, VK_CULL_MODE_BACK_BIT) // .setDepthTest(true, true, VK_COMPARE_OP_LESS) // .setColorBlendAttachment(PipelineBuilder::blendAlpha()) // .setLayout(pipelineLayout) // .setRenderPass(renderPass) // .build(device); class PipelineBuilder { public: PipelineBuilder(); // Shader stages PipelineBuilder& setShaders(VkPipelineShaderStageCreateInfo vert, VkPipelineShaderStageCreateInfo frag); // Vertex input PipelineBuilder& setVertexInput( const std::vector& bindings, const std::vector& attributes); // No vertex input (fullscreen quad generated in vertex shader) PipelineBuilder& setNoVertexInput(); // Input assembly PipelineBuilder& setTopology(VkPrimitiveTopology topology, VkBool32 primitiveRestart = VK_FALSE); // Rasterization PipelineBuilder& setRasterization(VkPolygonMode polygonMode, VkCullModeFlags cullMode, VkFrontFace frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE); // Depth test/write PipelineBuilder& setDepthTest(bool enable, bool writeEnable, VkCompareOp compareOp = VK_COMPARE_OP_LESS); // No depth test (default) PipelineBuilder& setNoDepthTest(); // Depth bias (for shadow maps) PipelineBuilder& setDepthBias(float constantFactor, float slopeFactor); // Color blend attachment PipelineBuilder& setColorBlendAttachment( VkPipelineColorBlendAttachmentState blendState); // No color attachment (depth-only pass) PipelineBuilder& setNoColorAttachment(); // Multisampling PipelineBuilder& setMultisample(VkSampleCountFlagBits samples); PipelineBuilder& setAlphaToCoverage(bool enable); // Pipeline layout PipelineBuilder& setLayout(VkPipelineLayout layout); // Render pass PipelineBuilder& setRenderPass(VkRenderPass renderPass, uint32_t subpass = 0); // Dynamic state PipelineBuilder& setDynamicStates(const std::vector& states); // Build the pipeline VkPipeline build(VkDevice device) const; // Common blend states static VkPipelineColorBlendAttachmentState blendDisabled(); static VkPipelineColorBlendAttachmentState blendAlpha(); static VkPipelineColorBlendAttachmentState blendPremultiplied(); static VkPipelineColorBlendAttachmentState blendAdditive(); private: std::vector shaderStages_; std::vector vertexBindings_; std::vector vertexAttributes_; VkPrimitiveTopology topology_ = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; VkBool32 primitiveRestart_ = VK_FALSE; VkPolygonMode polygonMode_ = VK_POLYGON_MODE_FILL; VkCullModeFlags cullMode_ = VK_CULL_MODE_NONE; VkFrontFace frontFace_ = VK_FRONT_FACE_COUNTER_CLOCKWISE; bool depthTestEnable_ = false; bool depthWriteEnable_ = false; VkCompareOp depthCompareOp_ = VK_COMPARE_OP_LESS; bool depthBiasEnable_ = false; float depthBiasConstant_ = 0.0f; float depthBiasSlope_ = 0.0f; VkSampleCountFlagBits msaaSamples_ = VK_SAMPLE_COUNT_1_BIT; bool alphaToCoverage_ = false; std::vector colorBlendAttachments_; VkPipelineLayout pipelineLayout_ = VK_NULL_HANDLE; VkRenderPass renderPass_ = VK_NULL_HANDLE; uint32_t subpass_ = 0; std::vector dynamicStates_; }; // Helper to create a pipeline layout from descriptor set layouts and push constant ranges VkPipelineLayout createPipelineLayout(VkDevice device, const std::vector& setLayouts, const std::vector& pushConstants = {}); // Helper to create a descriptor set layout from bindings VkDescriptorSetLayout createDescriptorSetLayout(VkDevice device, const std::vector& bindings); } // namespace rendering } // namespace wowee