/* Copyright (c) 2019-2025, Arm Limited and Contributors * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 the "License"; * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include "common/vk_common.h" #include "core/pipeline_layout.h" namespace vkb { class RenderPass; struct VertexInputState { std::vector bindings; std::vector attributes; }; struct InputAssemblyState { VkPrimitiveTopology topology{VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST}; VkBool32 primitive_restart_enable{VK_FALSE}; }; struct RasterizationState { VkBool32 depth_clamp_enable{VK_FALSE}; VkBool32 rasterizer_discard_enable{VK_FALSE}; VkPolygonMode polygon_mode{VK_POLYGON_MODE_FILL}; VkCullModeFlags cull_mode{VK_CULL_MODE_BACK_BIT}; VkFrontFace front_face{VK_FRONT_FACE_COUNTER_CLOCKWISE}; VkBool32 depth_bias_enable{VK_FALSE}; }; struct ViewportState { uint32_t viewport_count{1}; uint32_t scissor_count{1}; }; struct MultisampleState { VkSampleCountFlagBits rasterization_samples{VK_SAMPLE_COUNT_1_BIT}; VkBool32 sample_shading_enable{VK_FALSE}; float min_sample_shading{0.0f}; VkSampleMask sample_mask{0}; VkBool32 alpha_to_coverage_enable{VK_FALSE}; VkBool32 alpha_to_one_enable{VK_FALSE}; }; struct StencilOpState { VkStencilOp fail_op{VK_STENCIL_OP_REPLACE}; VkStencilOp pass_op{VK_STENCIL_OP_REPLACE}; VkStencilOp depth_fail_op{VK_STENCIL_OP_REPLACE}; VkCompareOp compare_op{VK_COMPARE_OP_NEVER}; }; struct DepthStencilState { VkBool32 depth_test_enable{VK_TRUE}; VkBool32 depth_write_enable{VK_TRUE}; // Note: Using reversed depth-buffer for increased precision, so Greater depth values are kept VkCompareOp depth_compare_op{VK_COMPARE_OP_GREATER}; VkBool32 depth_bounds_test_enable{VK_FALSE}; VkBool32 stencil_test_enable{VK_FALSE}; StencilOpState front{}; StencilOpState back{}; }; struct ColorBlendAttachmentState { VkBool32 blend_enable{VK_FALSE}; VkBlendFactor src_color_blend_factor{VK_BLEND_FACTOR_ONE}; VkBlendFactor dst_color_blend_factor{VK_BLEND_FACTOR_ZERO}; VkBlendOp color_blend_op{VK_BLEND_OP_ADD}; VkBlendFactor src_alpha_blend_factor{VK_BLEND_FACTOR_ONE}; VkBlendFactor dst_alpha_blend_factor{VK_BLEND_FACTOR_ZERO}; VkBlendOp alpha_blend_op{VK_BLEND_OP_ADD}; VkColorComponentFlags color_write_mask{VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT}; }; struct ColorBlendState { VkBool32 logic_op_enable{VK_FALSE}; VkLogicOp logic_op{VK_LOGIC_OP_CLEAR}; std::vector attachments; }; /// Helper class to create specialization constants for a Vulkan pipeline. The state tracks a pipeline globally, and not per shader. Two shaders using the same constant_id will have the same data. class SpecializationConstantState { public: void reset(); bool is_dirty() const; void clear_dirty(); template void set_constant(uint32_t constant_id, const T &data); void set_constant(uint32_t constant_id, const std::vector &data); void set_specialization_constant_state(const std::map> &state); const std::map> &get_specialization_constant_state() const; private: bool dirty{false}; // Map tracking state of the Specialization Constants std::map> specialization_constant_state; }; template inline void SpecializationConstantState::set_constant(std::uint32_t constant_id, const T &data) { set_constant(constant_id, to_bytes(static_cast(data))); } template <> inline void SpecializationConstantState::set_constant(std::uint32_t constant_id, const bool &data) { set_constant(constant_id, to_bytes(static_cast(data))); } class PipelineState { public: void reset(); void set_pipeline_layout(PipelineLayout &pipeline_layout); void set_render_pass(const RenderPass &render_pass); void set_specialization_constant(uint32_t constant_id, const std::vector &data); void set_vertex_input_state(const VertexInputState &vertex_input_state); void set_input_assembly_state(const InputAssemblyState &input_assembly_state); void set_rasterization_state(const RasterizationState &rasterization_state); void set_viewport_state(const ViewportState &viewport_state); void set_multisample_state(const MultisampleState &multisample_state); void set_depth_stencil_state(const DepthStencilState &depth_stencil_state); void set_color_blend_state(const ColorBlendState &color_blend_state); void set_subpass_index(uint32_t subpass_index); const PipelineLayout &get_pipeline_layout() const; const RenderPass *get_render_pass() const; const SpecializationConstantState &get_specialization_constant_state() const; const VertexInputState &get_vertex_input_state() const; const InputAssemblyState &get_input_assembly_state() const; const RasterizationState &get_rasterization_state() const; const ViewportState &get_viewport_state() const; const MultisampleState &get_multisample_state() const; const DepthStencilState &get_depth_stencil_state() const; const ColorBlendState &get_color_blend_state() const; uint32_t get_subpass_index() const; bool is_dirty() const; void clear_dirty(); private: bool dirty{false}; PipelineLayout *pipeline_layout{nullptr}; const RenderPass *render_pass{nullptr}; SpecializationConstantState specialization_constant_state{}; VertexInputState vertex_input_state{}; InputAssemblyState input_assembly_state{}; RasterizationState rasterization_state{}; ViewportState viewport_state{}; MultisampleState multisample_state{}; DepthStencilState depth_stencil_state{}; ColorBlendState color_blend_state{}; uint32_t subpass_index{0U}; }; } // namespace vkb