Skip to content

Commit 0efd073

Browse files
committed
[*] Add a graphics pipeline wrapper and builder
1 parent 7d2fc47 commit 0efd073

File tree

8 files changed

+551
-85
lines changed

8 files changed

+551
-85
lines changed

include/inexor/vulkan-renderer/render_graph.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include "inexor/vulkan-renderer/wrapper/fence.hpp"
77
#include "inexor/vulkan-renderer/wrapper/framebuffer.hpp"
88
#include "inexor/vulkan-renderer/wrapper/image.hpp"
9+
#include "inexor/vulkan-renderer/wrapper/pipeline.hpp"
10+
#include "inexor/vulkan-renderer/wrapper/pipeline_builder.hpp"
911
#include "inexor/vulkan-renderer/wrapper/pipeline_layout.hpp"
1012
#include "inexor/vulkan-renderer/wrapper/renderpass.hpp"
1113
#include "inexor/vulkan-renderer/wrapper/semaphore.hpp"
@@ -349,8 +351,8 @@ class PhysicalStage : public RenderGraphObject {
349351
friend RenderGraph;
350352

351353
private:
352-
VkPipeline m_pipeline{VK_NULL_HANDLE};
353354
std::unique_ptr<wrapper::PipelineLayout> m_pipeline_layout;
355+
std::unique_ptr<wrapper::GraphicsPipeline> m_pipeline;
354356

355357
protected:
356358
const wrapper::Device &m_device;
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#pragma once
2+
3+
#include <vulkan/vulkan_core.h>
4+
5+
#include <string>
6+
7+
namespace inexor::vulkan_renderer::wrapper {
8+
9+
// Forward declaration
10+
class Device;
11+
12+
// TODO: Compute pipelines
13+
14+
/// RAII wrapper for VkPipeline
15+
class GraphicsPipeline {
16+
private:
17+
const Device &m_device;
18+
VkPipeline m_pipeline{VK_NULL_HANDLE};
19+
std::string m_name;
20+
21+
public:
22+
/// Default constructor
23+
/// @param device The device wrapper
24+
/// @param pipeline_ci The pipeline create info
25+
/// @param name The internal debug name of the graphics pipeline
26+
GraphicsPipeline(const Device &device, const VkGraphicsPipelineCreateInfo &pipeline_ci, std::string name);
27+
GraphicsPipeline(const GraphicsPipeline &) = delete;
28+
GraphicsPipeline(GraphicsPipeline &&) noexcept;
29+
~GraphicsPipeline();
30+
31+
GraphicsPipeline &operator=(const GraphicsPipeline &) = delete;
32+
GraphicsPipeline &operator=(GraphicsPipeline &&) = delete;
33+
34+
[[nodiscard]] VkPipeline pipeline() const noexcept {
35+
return m_pipeline;
36+
}
37+
};
38+
39+
} // namespace inexor::vulkan_renderer::wrapper
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
#pragma once
2+
3+
#include <vulkan/vulkan_core.h>
4+
5+
#include "inexor/vulkan-renderer/wrapper/make_info.hpp"
6+
#include "inexor/vulkan-renderer/wrapper/pipeline.hpp"
7+
8+
#include <memory>
9+
#include <string>
10+
#include <vector>
11+
12+
namespace inexor::vulkan_renderer::wrapper {
13+
14+
// Forward declarations
15+
class Device;
16+
17+
/// Builder class for VkPipelineCreateInfo
18+
class GraphicsPipelineBuilder {
19+
private:
20+
const Device &m_device;
21+
VkPipelineVertexInputStateCreateInfo m_vertex_input_sci{make_info<VkPipelineVertexInputStateCreateInfo>()};
22+
23+
VkPipelineInputAssemblyStateCreateInfo m_input_assembly_sci{make_info<VkPipelineInputAssemblyStateCreateInfo>({
24+
.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
25+
.primitiveRestartEnable = VK_FALSE,
26+
})};
27+
28+
VkPipelineTessellationStateCreateInfo m_tesselation_sci{make_info<VkPipelineTessellationStateCreateInfo>()};
29+
VkPipelineViewportStateCreateInfo m_viewport_sci{make_info<VkPipelineViewportStateCreateInfo>()};
30+
31+
VkPipelineRasterizationStateCreateInfo m_rasterization_sci{make_info<VkPipelineRasterizationStateCreateInfo>({
32+
.polygonMode = VK_POLYGON_MODE_FILL,
33+
.cullMode = VK_CULL_MODE_BACK_BIT,
34+
.frontFace = VK_FRONT_FACE_CLOCKWISE,
35+
.lineWidth = 1.0f,
36+
})};
37+
38+
// TODO: Support more options for multisampling
39+
VkPipelineMultisampleStateCreateInfo m_multisample_sci{make_info<VkPipelineMultisampleStateCreateInfo>({
40+
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
41+
.minSampleShading = 1.0f,
42+
})};
43+
44+
VkPipelineDepthStencilStateCreateInfo m_depth_stencil_sci{make_info<VkPipelineDepthStencilStateCreateInfo>()};
45+
VkPipelineColorBlendStateCreateInfo m_color_blend_sci{make_info<VkPipelineColorBlendStateCreateInfo>()};
46+
VkPipelineDynamicStateCreateInfo m_dynamic_states_sci{make_info<VkPipelineDynamicStateCreateInfo>()};
47+
48+
VkPipelineLayout m_pipeline_layout{VK_NULL_HANDLE};
49+
VkRenderPass m_render_pass{VK_NULL_HANDLE};
50+
51+
std::vector<VkDynamicState> m_dynamic_states;
52+
std::vector<VkViewport> m_viewports;
53+
std::vector<VkRect2D> m_scissors;
54+
std::vector<VkPipelineShaderStageCreateInfo> m_shader_stages;
55+
std::vector<VkVertexInputBindingDescription> m_vertex_input_binding_descriptions;
56+
std::vector<VkVertexInputAttributeDescription> m_vertex_input_attribute_descriptions;
57+
std::vector<VkPipelineColorBlendAttachmentState> m_color_blend_attachment_states;
58+
59+
public:
60+
/// Default constructor
61+
/// @param device The device wrapper
62+
GraphicsPipelineBuilder(const Device &device);
63+
GraphicsPipelineBuilder(const GraphicsPipelineBuilder &) = delete;
64+
GraphicsPipelineBuilder(GraphicsPipelineBuilder &&other) noexcept;
65+
~GraphicsPipelineBuilder() = default;
66+
67+
GraphicsPipelineBuilder &operator=(const GraphicsPipelineBuilder &) = delete;
68+
GraphicsPipelineBuilder &operator=(GraphicsPipelineBuilder &&) = delete;
69+
70+
/// Add a shader stage
71+
/// @param shader_stage The shader stage to add
72+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
73+
[[nodiscard]] GraphicsPipelineBuilder &add_shader(const VkPipelineShaderStageCreateInfo &shader_stage);
74+
75+
/// Add a vertex input attribute description
76+
/// @param description The vertex input attribute description
77+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
78+
[[nodiscard]] GraphicsPipelineBuilder &
79+
add_vertex_input_attribute(const VkVertexInputAttributeDescription &description);
80+
81+
/// Add a vertex input binding description
82+
/// @param description The vertex input binding descriptions
83+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
84+
[[nodiscard]] GraphicsPipelineBuilder &add_vertex_input_binding(const VkVertexInputBindingDescription &description);
85+
86+
/// Add a color blend attachment
87+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
88+
[[nodiscard]] GraphicsPipelineBuilder &
89+
add_color_blend_attachment(const VkPipelineColorBlendAttachmentState &attachment);
90+
91+
/// Build the graphics pipeline with specified pipeline create flags
92+
/// @param create_flags The pipeline create flags
93+
/// @param name The debug name of the graphics pipeline
94+
[[nodiscard]] std::unique_ptr<GraphicsPipeline> build(std::string name);
95+
96+
/// Set the color blend state manually
97+
/// @param color_blend_state The color blend state
98+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
99+
[[nodiscard]] GraphicsPipelineBuilder &
100+
set_color_blend(const VkPipelineColorBlendStateCreateInfo &color_blend_state);
101+
102+
/// Set all color blend attachments manually
103+
/// @note You should prefer to use `add_color_blend_attachment` instead
104+
/// @param attachments The color blend attachments
105+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
106+
[[nodiscard]] GraphicsPipelineBuilder &
107+
set_color_blend_attachments(const std::vector<VkPipelineColorBlendAttachmentState> &attachments);
108+
109+
/// Enables or disabled culling
110+
/// @warning Disabling culling will have a significant performance impact
111+
/// @param culling_enabled ``true`` if culling is enabled
112+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
113+
[[nodiscard]] GraphicsPipelineBuilder &set_culling_mode(VkBool32 culling_enabled);
114+
115+
/// Set the depth stencil state
116+
/// @param depth_stencil The depth stencil state
117+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
118+
[[nodiscard]] GraphicsPipelineBuilder &
119+
set_depth_stencil(const VkPipelineDepthStencilStateCreateInfo &depth_stencil);
120+
121+
/// Set the dynamic states of the graphics pipeline
122+
/// @param dynamic_states The dynamic states of the graphics pipeline
123+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
124+
[[nodiscard]] GraphicsPipelineBuilder &set_dynamic_states(const std::vector<VkDynamicState> &dynamic_states);
125+
126+
/// Set the input assembly state create info
127+
/// @note If you just want to set the triangle topology, call ``set_triangle_topology`` instead, because this is the
128+
/// most powerful method of this method in case you really need to overwrite it
129+
/// @param input_assembly_sci The pipeline input state create info
130+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
131+
[[nodiscard]] GraphicsPipelineBuilder &
132+
set_input_assembly(const VkPipelineInputAssemblyStateCreateInfo &input_assembly_sci);
133+
134+
/// Set the line width of rasterization
135+
/// @param line_width The line width of rasterization
136+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
137+
[[nodiscard]] GraphicsPipelineBuilder &set_line_width(float width);
138+
139+
/// Store the pipeline layout
140+
/// @param layout The pipeline layout
141+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
142+
[[nodiscard]] GraphicsPipelineBuilder &set_pipeline_layout(VkPipelineLayout layout);
143+
144+
/// Set the triangle topology
145+
/// @param topology the primitive topology
146+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
147+
[[nodiscard]] GraphicsPipelineBuilder &set_primitive_topology(VkPrimitiveTopology topology);
148+
149+
/// Set the rasterization state of the graphics pipeline manually
150+
/// @param rasterization_state The rasterization state
151+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
152+
[[nodiscard]] GraphicsPipelineBuilder &
153+
set_rasterization(const VkPipelineRasterizationStateCreateInfo &rasterization);
154+
155+
/// Set the render pass
156+
/// @param render_pass The render pass
157+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
158+
[[nodiscard]] GraphicsPipelineBuilder &set_render_pass(VkRenderPass render_pass);
159+
160+
/// Set the scissor data in VkPipelineViewportStateCreateInfo
161+
/// There is another method called set_scissors in case multiple scissors will be used
162+
/// @param scissors The scissors in in VkPipelineViewportStateCreateInfo
163+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
164+
[[nodiscard]] GraphicsPipelineBuilder &set_scissor(const VkRect2D &scissor);
165+
166+
/// Set the viewport data in VkPipelineViewportStateCreateInfo
167+
/// There is another method called set_scissors in case multiple scissors will be used
168+
/// @param scissor The scissor in in VkPipelineViewportStateCreateInfo
169+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
170+
[[nodiscard]] GraphicsPipelineBuilder &set_scissors(const std::vector<VkRect2D> &scissors);
171+
172+
/// Set the shader stage
173+
/// @param shader_stages The shader stages
174+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
175+
[[nodiscard]] GraphicsPipelineBuilder &
176+
set_shaders(const std::vector<VkPipelineShaderStageCreateInfo> &shader_stages);
177+
178+
/// Set the tesselation state create info
179+
/// @param control_points The tesselation control point count
180+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
181+
[[nodiscard]] GraphicsPipelineBuilder &set_tesselation(std::uint32_t control_points);
182+
183+
/// Set the vertex input attribute descriptions manually
184+
/// You should prefer to use ``add_vertex_input_attribute`` instead
185+
/// @param descriptions The vertex input attribute descriptions
186+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
187+
[[nodiscard]] GraphicsPipelineBuilder &
188+
set_vertex_input_attributes(const std::vector<VkVertexInputAttributeDescription> &descriptions);
189+
190+
/// Set the vertex input binding descriptions manually
191+
/// You should prefer to use ``add_vertex_input_binding`` instead
192+
/// @param descriptions The vertex input binding descriptions
193+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
194+
[[nodiscard]] GraphicsPipelineBuilder &
195+
set_vertex_input_bindings(const std::vector<VkVertexInputBindingDescription> &descriptions);
196+
197+
/// Set the viewport in VkPipelineViewportStateCreateInfo
198+
/// There is another method called set_viewports in case multiple viewports will be used
199+
/// @param viewport The viewport in VkPipelineViewportStateCreateInfo
200+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
201+
[[nodiscard]] GraphicsPipelineBuilder &set_viewport(const VkViewport &viewport);
202+
203+
/// Set the viewport in VkPipelineViewportStateCreateInfo
204+
/// @param viewports The viewports in VkPipelineViewportStateCreateInfo
205+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
206+
[[nodiscard]] GraphicsPipelineBuilder &set_viewports(const std::vector<VkViewport> &viewports);
207+
208+
/// Set the wireframe mode
209+
/// @param wireframe ``true`` if wireframe is enabled
210+
/// @return A reference to the dereferenced this pointer (allows method calls to be chained)
211+
[[nodiscard]] GraphicsPipelineBuilder &set_wireframe(VkBool32 wireframe);
212+
};
213+
214+
} // namespace inexor::vulkan_renderer::wrapper

src/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ set(INEXOR_SOURCE_FILES
3434
vulkan-renderer/wrapper/gpu_texture.cpp
3535
vulkan-renderer/wrapper/image.cpp
3636
vulkan-renderer/wrapper/instance.cpp
37+
vulkan-renderer/wrapper/pipeline.cpp
38+
vulkan-renderer/wrapper/pipeline_builder.cpp
3739
vulkan-renderer/wrapper/pipeline_layout.cpp
3840
vulkan-renderer/wrapper/make_info.cpp
3941
vulkan-renderer/wrapper/renderpass.cpp

0 commit comments

Comments
 (0)