7#include "gfx_pipeline_vulkan_intf.hpp"
8#include "gfx_device_vulkan_impl.hpp"
9#include "gfx_surface_vulkan_intf.hpp"
10#include "../telemetry/telemetry.hpp"
11#include "../macros.hpp"
14#include <vulkan/vulkan.hpp>
16hi_export_module(hikogui.GFX : gfx_pipeline_impl);
18hi_export
namespace hi {
inline namespace v1 {
20[[nodiscard]]
inline gfx_device *gfx_pipeline::device() const noexcept
22 hi_axiom_not_null(surface);
23 return surface->device();
26inline void gfx_pipeline::draw_in_command_buffer(vk::CommandBuffer commandBuffer, draw_context
const& context)
28 commandBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, intrinsic);
31 if (descriptorSetVersion < getDescriptorSetVersion()) {
32 descriptorSetVersion = getDescriptorSetVersion();
34 hi_axiom_not_null(device());
35 device()->updateDescriptorSets(createWriteDescriptorSet(), {});
38 commandBuffer.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipelineLayout, 0, {descriptorSet}, {});
42inline void gfx_pipeline::build_descriptor_sets()
44 auto const descriptorSetLayoutBindings = createDescriptorSetLayoutBindings();
46 if (ssize(descriptorSetLayoutBindings) == 0) {
48 descriptorSet =
nullptr;
52 auto const descriptorSetLayoutCreateInfo = vk::DescriptorSetLayoutCreateInfo{
53 vk::DescriptorSetLayoutCreateFlags(),
54 narrow_cast<uint32_t>(descriptorSetLayoutBindings.size()),
55 descriptorSetLayoutBindings.data()};
57 hi_axiom_not_null(device());
58 descriptorSetLayout = device()->createDescriptorSetLayout(descriptorSetLayoutCreateInfo);
60 auto const descriptorPoolSizes =
61 transform<std::vector<vk::DescriptorPoolSize>>(descriptorSetLayoutBindings, [](
auto x) -> vk::DescriptorPoolSize {
62 return {x.descriptorType, narrow_cast<uint32_t>(x.descriptorCount)};
65 descriptorPool = device()->createDescriptorPool(
66 {vk::DescriptorPoolCreateFlags(),
68 narrow_cast<uint32_t>(descriptorPoolSizes.size()),
69 descriptorPoolSizes.data()});
71 auto const descriptorSetLayouts =
std::array{descriptorSetLayout};
73 auto const descriptorSets = device()->allocateDescriptorSets(
74 {descriptorPool, narrow_cast<uint32_t>(descriptorSetLayouts.size()), descriptorSetLayouts.data()});
76 descriptorSet = descriptorSets.
at(0);
77 descriptorSetVersion = 0;
80inline void gfx_pipeline::teardown_descriptor_sets()
86 hi_axiom_not_null(device());
87 device()->destroy(descriptorPool);
88 device()->destroy(descriptorSetLayout);
89 descriptorSet =
nullptr;
92inline vk::PipelineDepthStencilStateCreateInfo gfx_pipeline::getPipelineDepthStencilStateCreateInfo()
const
96 vk::PipelineDepthStencilStateCreateFlags(),
99 vk::CompareOp::eGreaterOrEqual,
102 vk::StencilOpState(),
103 vk::StencilOpState(),
115 vk::BlendFactor::eOne,
116 vk::BlendFactor::eOneMinusSrcAlpha,
118 vk::BlendFactor::eOne,
119 vk::BlendFactor::eOneMinusSrcAlpha,
121 vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB |
122 vk::ColorComponentFlagBits::eA}};
125inline void gfx_pipeline::build_pipeline(vk::RenderPass renderPass, uint32_t renderSubpass, vk::Extent2D _extent)
127 hi_log_info(
"buildPipeline previous size ({}, {})", extent.width, extent.height);
130 const auto pushConstantRanges = createPushConstantRanges();
131 const auto vertexInputBindingDescription = createVertexInputBindingDescription();
132 const auto vertexInputAttributeDescriptions = createVertexInputAttributeDescriptions();
133 const auto shaderStages = createShaderStages();
137 descriptorSetLayouts.
push_back(descriptorSetLayout);
140 hi_axiom_not_null(device());
141 pipelineLayout = device()->createPipelineLayout(
142 {vk::PipelineLayoutCreateFlags(),
143 narrow_cast<uint32_t>(descriptorSetLayouts.
size()),
144 descriptorSetLayouts.
data(),
145 narrow_cast<uint32_t>(pushConstantRanges.size()),
146 pushConstantRanges.data()});
148 const vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = {
149 vk::PipelineVertexInputStateCreateFlags(),
151 &vertexInputBindingDescription,
152 narrow_cast<uint32_t>(vertexInputAttributeDescriptions.size()),
153 vertexInputAttributeDescriptions.data()};
155 const vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo = {
156 vk::PipelineInputAssemblyStateCreateFlags(), vk::PrimitiveTopology::eTriangleList, VK_FALSE};
161 narrow_cast<float>(extent.width),
162 narrow_cast<float>(extent.height),
167 auto const scissor = vk::Rect2D{vk::Offset2D{0, 0}, extent};
171 const vk::PipelineViewportStateCreateInfo pipelineViewportStateCreateInfo = {
172 vk::PipelineViewportStateCreateFlags(),
173 narrow_cast<uint32_t>(viewports.
size()),
175 narrow_cast<uint32_t>(scissors.size()),
178 const vk::PipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo = {
179 vk::PipelineRasterizationStateCreateFlags(),
182 vk::PolygonMode::eFill,
183 vk::CullModeFlagBits::eBack,
184 vk::FrontFace::eCounterClockwise,
192 const vk::PipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo = {
193 vk::PipelineMultisampleStateCreateFlags(),
194 vk::SampleCountFlagBits::e1,
202 auto const pipelineDepthStencilStateCreateInfo = getPipelineDepthStencilStateCreateInfo();
206 auto const pipelineColorBlendAttachmentStates = getPipelineColorBlendAttachmentStates();
208 const vk::PipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo = {
209 vk::PipelineColorBlendStateCreateFlags(),
212 narrow_cast<uint32_t>(pipelineColorBlendAttachmentStates.size()),
213 pipelineColorBlendAttachmentStates.data()};
215 auto const dynamicStates =
std::array{vk::DynamicState::eScissor};
217 auto const pipelineDynamicStateInfo = vk::PipelineDynamicStateCreateInfo{
218 vk::PipelineDynamicStateCreateFlags(), narrow_cast<uint32_t>(dynamicStates.size()), dynamicStates.
data()};
220 const vk::GraphicsPipelineCreateInfo graphicsPipelineCreateInfo = {
221 vk::PipelineCreateFlags(),
222 narrow_cast<uint32_t>(shaderStages.size()),
224 &pipelineVertexInputStateCreateInfo,
225 &pipelineInputAssemblyStateCreateInfo,
227 &pipelineViewportStateCreateInfo,
228 &pipelineRasterizationStateCreateInfo,
229 &pipelineMultisampleStateCreateInfo,
230 &pipelineDepthStencilStateCreateInfo,
231 &pipelineColorBlendStateCreateInfo,
232 &pipelineDynamicStateInfo,
240 hi_axiom_not_null(device());
241 intrinsic = device()->createGraphicsPipeline(vk::PipelineCache(), graphicsPipelineCreateInfo);
242 hi_log_info(
"/buildPipeline new size ({}, {})", extent.width, extent.height);
245inline void gfx_pipeline::teardown_pipeline()
247 hi_axiom_not_null(device());
248 device()->destroy(intrinsic);
249 device()->destroy(pipelineLayout);
252inline void gfx_pipeline::build_for_new_device()
254 build_vertex_buffers();
257inline void gfx_pipeline::teardown_for_device_lost()
259 teardown_vertex_buffers();
262inline void gfx_pipeline::build_for_new_swapchain(vk::RenderPass renderPass, uint32_t renderSubpass, vk::Extent2D _extent)
266 build_descriptor_sets();
267 build_pipeline(renderPass, renderSubpass, _extent);
270inline void gfx_pipeline::teardown_for_swapchain_lost()
273 teardown_descriptor_sets();
The HikoGUI namespace.
Definition array_generic.hpp:20
DOXYGEN BUG.
Definition algorithm_misc.hpp:20