/* 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. */ #include "pipeline_state.h" #include "core/render_pass.h" bool operator==(const VkVertexInputAttributeDescription &lhs, const VkVertexInputAttributeDescription &rhs) { return std::tie(lhs.binding, lhs.format, lhs.location, lhs.offset) == std::tie(rhs.binding, rhs.format, rhs.location, rhs.offset); } bool operator==(const VkVertexInputBindingDescription &lhs, const VkVertexInputBindingDescription &rhs) { return std::tie(lhs.binding, lhs.inputRate, lhs.stride) == std::tie(rhs.binding, rhs.inputRate, rhs.stride); } bool operator==(const vkb::ColorBlendAttachmentState &lhs, const vkb::ColorBlendAttachmentState &rhs) { return std::tie(lhs.alpha_blend_op, lhs.blend_enable, lhs.color_blend_op, lhs.color_write_mask, lhs.dst_alpha_blend_factor, lhs.dst_color_blend_factor, lhs.src_alpha_blend_factor, lhs.src_color_blend_factor) == std::tie(rhs.alpha_blend_op, rhs.blend_enable, rhs.color_blend_op, rhs.color_write_mask, rhs.dst_alpha_blend_factor, rhs.dst_color_blend_factor, rhs.src_alpha_blend_factor, rhs.src_color_blend_factor); } bool operator!=(const vkb::StencilOpState &lhs, const vkb::StencilOpState &rhs) { return std::tie(lhs.compare_op, lhs.depth_fail_op, lhs.fail_op, lhs.pass_op) != std::tie(rhs.compare_op, rhs.depth_fail_op, rhs.fail_op, rhs.pass_op); } bool operator!=(const vkb::VertexInputState &lhs, const vkb::VertexInputState &rhs) { return lhs.attributes != rhs.attributes || lhs.bindings != rhs.bindings; } bool operator!=(const vkb::InputAssemblyState &lhs, const vkb::InputAssemblyState &rhs) { return std::tie(lhs.primitive_restart_enable, lhs.topology) != std::tie(rhs.primitive_restart_enable, rhs.topology); } bool operator!=(const vkb::RasterizationState &lhs, const vkb::RasterizationState &rhs) { return std::tie(lhs.cull_mode, lhs.depth_bias_enable, lhs.depth_clamp_enable, lhs.front_face, lhs.front_face, lhs.polygon_mode, lhs.rasterizer_discard_enable) != std::tie(rhs.cull_mode, rhs.depth_bias_enable, rhs.depth_clamp_enable, rhs.front_face, rhs.front_face, rhs.polygon_mode, rhs.rasterizer_discard_enable); } bool operator!=(const vkb::ViewportState &lhs, const vkb::ViewportState &rhs) { return lhs.viewport_count != rhs.viewport_count || lhs.scissor_count != rhs.scissor_count; } bool operator!=(const vkb::MultisampleState &lhs, const vkb::MultisampleState &rhs) { return std::tie(lhs.alpha_to_coverage_enable, lhs.alpha_to_one_enable, lhs.min_sample_shading, lhs.rasterization_samples, lhs.sample_mask, lhs.sample_shading_enable) != std::tie(rhs.alpha_to_coverage_enable, rhs.alpha_to_one_enable, rhs.min_sample_shading, rhs.rasterization_samples, rhs.sample_mask, rhs.sample_shading_enable); } bool operator!=(const vkb::DepthStencilState &lhs, const vkb::DepthStencilState &rhs) { return std::tie(lhs.depth_bounds_test_enable, lhs.depth_compare_op, lhs.depth_test_enable, lhs.depth_write_enable, lhs.stencil_test_enable) != std::tie(rhs.depth_bounds_test_enable, rhs.depth_compare_op, rhs.depth_test_enable, rhs.depth_write_enable, rhs.stencil_test_enable) || lhs.back != rhs.back || lhs.front != rhs.front; } bool operator!=(const vkb::ColorBlendState &lhs, const vkb::ColorBlendState &rhs) { return std::tie(lhs.logic_op, lhs.logic_op_enable) != std::tie(rhs.logic_op, rhs.logic_op_enable) || lhs.attachments.size() != rhs.attachments.size() || !std::equal(lhs.attachments.begin(), lhs.attachments.end(), rhs.attachments.begin(), [](const vkb::ColorBlendAttachmentState &lhs, const vkb::ColorBlendAttachmentState &rhs) { return lhs == rhs; }); } namespace vkb { void SpecializationConstantState::reset() { if (dirty) { specialization_constant_state.clear(); } dirty = false; } bool SpecializationConstantState::is_dirty() const { return dirty; } void SpecializationConstantState::clear_dirty() { dirty = false; } void SpecializationConstantState::set_constant(uint32_t constant_id, const std::vector &value) { auto data = specialization_constant_state.find(constant_id); if (data != specialization_constant_state.end() && data->second == value) { return; } dirty = true; specialization_constant_state[constant_id] = value; } void SpecializationConstantState::set_specialization_constant_state(const std::map> &state) { specialization_constant_state = state; } const std::map> &SpecializationConstantState::get_specialization_constant_state() const { return specialization_constant_state; } void PipelineState::reset() { clear_dirty(); pipeline_layout = nullptr; render_pass = nullptr; specialization_constant_state.reset(); vertex_input_state = {}; input_assembly_state = {}; rasterization_state = {}; multisample_state = {}; depth_stencil_state = {}; color_blend_state = {}; subpass_index = {0U}; } void PipelineState::set_pipeline_layout(PipelineLayout &new_pipeline_layout) { if (pipeline_layout) { if (pipeline_layout->get_handle() != new_pipeline_layout.get_handle()) { pipeline_layout = &new_pipeline_layout; dirty = true; } } else { pipeline_layout = &new_pipeline_layout; dirty = true; } } void PipelineState::set_render_pass(const RenderPass &new_render_pass) { if (render_pass) { if (render_pass->get_handle() != new_render_pass.get_handle()) { render_pass = &new_render_pass; dirty = true; } } else { render_pass = &new_render_pass; dirty = true; } } void PipelineState::set_specialization_constant(uint32_t constant_id, const std::vector &data) { specialization_constant_state.set_constant(constant_id, data); if (specialization_constant_state.is_dirty()) { dirty = true; } } void PipelineState::set_vertex_input_state(const VertexInputState &new_vertex_input_state) { if (vertex_input_state != new_vertex_input_state) { vertex_input_state = new_vertex_input_state; dirty = true; } } void PipelineState::set_input_assembly_state(const InputAssemblyState &new_input_assembly_state) { if (input_assembly_state != new_input_assembly_state) { input_assembly_state = new_input_assembly_state; dirty = true; } } void PipelineState::set_rasterization_state(const RasterizationState &new_rasterization_state) { if (rasterization_state != new_rasterization_state) { rasterization_state = new_rasterization_state; dirty = true; } } void PipelineState::set_viewport_state(const ViewportState &new_viewport_state) { if (viewport_state != new_viewport_state) { viewport_state = new_viewport_state; dirty = true; } } void PipelineState::set_multisample_state(const MultisampleState &new_multisample_state) { if (multisample_state != new_multisample_state) { multisample_state = new_multisample_state; dirty = true; } } void PipelineState::set_depth_stencil_state(const DepthStencilState &new_depth_stencil_state) { if (depth_stencil_state != new_depth_stencil_state) { depth_stencil_state = new_depth_stencil_state; dirty = true; } } void PipelineState::set_color_blend_state(const ColorBlendState &new_color_blend_state) { if (color_blend_state != new_color_blend_state) { color_blend_state = new_color_blend_state; dirty = true; } } void PipelineState::set_subpass_index(uint32_t new_subpass_index) { if (subpass_index != new_subpass_index) { subpass_index = new_subpass_index; dirty = true; } } const PipelineLayout &PipelineState::get_pipeline_layout() const { assert(pipeline_layout && "Graphics state Pipeline layout is not set"); return *pipeline_layout; } const RenderPass *PipelineState::get_render_pass() const { return render_pass; } const SpecializationConstantState &PipelineState::get_specialization_constant_state() const { return specialization_constant_state; } const VertexInputState &PipelineState::get_vertex_input_state() const { return vertex_input_state; } const InputAssemblyState &PipelineState::get_input_assembly_state() const { return input_assembly_state; } const RasterizationState &PipelineState::get_rasterization_state() const { return rasterization_state; } const ViewportState &PipelineState::get_viewport_state() const { return viewport_state; } const MultisampleState &PipelineState::get_multisample_state() const { return multisample_state; } const DepthStencilState &PipelineState::get_depth_stencil_state() const { return depth_stencil_state; } const ColorBlendState &PipelineState::get_color_blend_state() const { return color_blend_state; } uint32_t PipelineState::get_subpass_index() const { return subpass_index; } bool PipelineState::is_dirty() const { return dirty || specialization_constant_state.is_dirty(); } void PipelineState::clear_dirty() { dirty = false; specialization_constant_state.clear_dirty(); } } // namespace vkb