Skip to content

Commit 422f59e

Browse files
committed
[*] Work in progress but broken
1 parent 80a099c commit 422f59e

File tree

4 files changed

+55
-98
lines changed

4 files changed

+55
-98
lines changed

include/inexor/vulkan-renderer/wrapper/pipelines/graphics_pipeline.hpp

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,47 @@ namespace inexor::vulkan_renderer::wrapper::pipelines {
3434

3535
// TODO: Implement RAII wrapper for ComputePipeline
3636

37+
/// When creating a graphics pipeline, the lifetime of certain data which is used to create the pipeline must be
38+
/// ensured. In particular, the VkGraphicsPipelineCreateInfo struct must not be stored, however, the memory to which the
39+
/// pointers inside of VkGraphicsPipelineCreateInfo point to must be stored. For example, VkGraphicsPipelineCreateInfo
40+
/// has a member VkPipelineViewportStateCreateInfo, which itself has a pointer that point to VkViewport data, for
41+
/// example. This means we must make sure the lifetime of all data that the pointers point to must be preserved.
42+
/// Initially, we collected all the data to create the graphics pipeline in GraphicsPipelineBuilder, and reset all the
43+
/// data of the builder after the build() method has been called. However, this is wrong, because the lifetime of the
44+
/// data ends with calling reset(). This causes some bugs which are hard to find.
45+
struct GraphicsPipelineSetupData {
46+
// @TODO Add whatever we need here!
47+
// This is the underlying data for the create info structures
48+
std::vector<VkPipelineShaderStageCreateInfo> m_shader_stages;
49+
std::vector<VkVertexInputBindingDescription> m_vertex_input_binding_descriptions;
50+
std::vector<VkVertexInputAttributeDescription> m_vertex_input_attribute_descriptions;
51+
std::vector<VkPipelineColorBlendAttachmentState> m_color_blend_attachment_states;
52+
std::vector<VkViewport> m_viewports;
53+
std::vector<VkRect2D> m_scissors;
54+
std::vector<VkPushConstantRange> m_push_constant_ranges;
55+
std::vector<VkDescriptorSetLayout> m_descriptor_set_layouts;
56+
VkRenderPass m_render_pass;
57+
VkFormat m_depth_attachment_format;
58+
VkFormat m_stencil_attachment_format;
59+
std::vector<VkFormat> m_color_attachments;
60+
std::vector<VkDynamicState> m_dynamic_states;
61+
VkPipelineLayout m_pipeline_layout;
62+
63+
// These are the create info structures required to fill the VkGraphicsPipelineCreateInfo
64+
VkPipelineVertexInputStateCreateInfo m_vertex_input_sci;
65+
VkPipelineInputAssemblyStateCreateInfo m_input_assembly_sci;
66+
VkPipelineTessellationStateCreateInfo m_tesselation_sci;
67+
VkPipelineViewportStateCreateInfo m_viewport_sci;
68+
VkPipelineRasterizationStateCreateInfo m_rasterization_sci;
69+
VkPipelineDepthStencilStateCreateInfo m_depth_stencil_sci;
70+
VkPipelineRenderingCreateInfo m_pipeline_rendering_ci;
71+
VkPipelineMultisampleStateCreateInfo m_multisample_sci;
72+
VkPipelineColorBlendStateCreateInfo m_color_blend_sci;
73+
VkPipelineDynamicStateCreateInfo m_dynamic_states_sci;
74+
75+
// @TODO: Implement move constructor for GraphicsPipelineSetupData?
76+
};
77+
3778
/// RAII wrapper for graphics pipelines
3879
class GraphicsPipeline {
3980
friend class commands::CommandBuffer;
@@ -42,6 +83,7 @@ class GraphicsPipeline {
4283
private:
4384
const Device &m_device;
4485
std::string m_name;
86+
GraphicsPipelineSetupData m_pipeline_setup_data;
4587

4688
VkPipeline m_pipeline;
4789
std::unique_ptr<PipelineLayout> m_pipeline_layout;
@@ -52,12 +94,12 @@ class GraphicsPipeline {
5294
/// @param pipeline_cache The Vulkan pipeline cache
5395
/// @param descriptor_set_layouts The descriptor set layouts in the pipeline layout
5496
/// @param push_constant_ranges The push constant ranges in the pipeline layout
55-
/// @param pipeline_ci The pipeline create info
97+
/// @param pipeline_setup_data The graphics pipeline setup data
5698
/// @param name The internal debug name of the graphics pipeline
5799
GraphicsPipeline(const Device &device, const PipelineCache &pipeline_cache,
58100
std::span<const VkDescriptorSetLayout> descriptor_set_layouts,
59101
std::span<const VkPushConstantRange> push_constant_ranges,
60-
VkGraphicsPipelineCreateInfo pipeline_ci, std::string name);
102+
GraphicsPipelineSetupData pipeline_setup_data, std::string name);
61103

62104
GraphicsPipeline(const GraphicsPipeline &) = delete;
63105
GraphicsPipeline(GraphicsPipeline &&) noexcept;

include/inexor/vulkan-renderer/wrapper/pipelines/graphics_pipeline_builder.hpp

Lines changed: 3 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -40,78 +40,14 @@ class PipelineCache;
4040
/// to implement checks in case required fields are not set in this builder.
4141
class GraphicsPipelineBuilder {
4242
private:
43-
/// The device wrapper reference
43+
/// The device wrapper
4444
const Device &m_device;
45-
4645
/// The Vulkan pipeline cache
4746
const PipelineCache &m_pipeline_cache;
48-
49-
// We are not using member initializers here:
50-
// Note that all members are initialized in the reset() method
51-
// This method is also called after the graphics pipeline has been created,
52-
// allowing one instance of GraphicsPipelineBuilder to be reused
53-
54-
// With the builder we can either call add_shader or set_shaders
55-
std::vector<VkPipelineShaderStageCreateInfo> m_shader_stages;
56-
57-
std::vector<VkVertexInputBindingDescription> m_vertex_input_binding_descriptions;
58-
std::vector<VkVertexInputAttributeDescription> m_vertex_input_attribute_descriptions;
59-
// With the builder we can fill vertex binding descriptions and vertex attribute descriptions in here
60-
VkPipelineVertexInputStateCreateInfo m_vertex_input_sci;
61-
62-
// With the builder we can set topology in here
63-
VkPipelineInputAssemblyStateCreateInfo m_input_assembly_sci;
64-
65-
// With the builder we can set the patch control point count in here
66-
VkPipelineTessellationStateCreateInfo m_tesselation_sci;
67-
68-
std::vector<VkViewport> m_viewports;
69-
std::vector<VkRect2D> m_scissors;
70-
// With the builder we can set viewport(s) and scissor(s) in here
71-
VkPipelineViewportStateCreateInfo m_viewport_sci;
72-
73-
// With the builder we can set polygon mode, cull mode, front face, and line width
74-
// TODO: Implement methods to enable depth bias and for setting the depth bias parameters
75-
VkPipelineRasterizationStateCreateInfo m_rasterization_sci;
76-
77-
// With the builder we can't set individial fields of this struct,
78-
// since it's easier to specify an entire VkPipelineDepthStencilStateCreateInfo struct to the builder instead
79-
VkPipelineDepthStencilStateCreateInfo m_depth_stencil_sci;
80-
81-
VkRenderPass m_render_pass;
82-
83-
/// This is used for dynamic rendering
84-
VkFormat m_depth_attachment_format;
85-
VkFormat m_stencil_attachment_format;
86-
std::vector<VkFormat> m_color_attachments;
87-
88-
VkPipelineRenderingCreateInfo m_pipeline_rendering_ci;
89-
90-
// With the builder we can set rasterization samples and min sample shading
91-
// TODO: Expose more multisampling parameters if desired
92-
VkPipelineMultisampleStateCreateInfo m_multisample_sci;
93-
94-
// With the builder we can't set individial fields of this struct,
95-
// since it's easier to specify an entire VkPipelineColorBlendStateCreateInfo struct to the builder instead
96-
VkPipelineColorBlendStateCreateInfo m_color_blend_sci;
97-
98-
std::vector<VkDynamicState> m_dynamic_states;
99-
// This will be filled in the build() method
100-
VkPipelineDynamicStateCreateInfo m_dynamic_states_sci;
101-
102-
/// The layout of the graphics pipeline
103-
VkPipelineLayout m_pipeline_layout;
104-
105-
// With the builder we can either call add_color_blend_attachment or set_color_blend_attachments
106-
std::vector<VkPipelineColorBlendAttachmentState> m_color_blend_attachment_states;
107-
108-
/// The push constant ranges of the graphics pass
109-
std::vector<VkPushConstantRange> m_push_constant_ranges;
110-
111-
std::vector<VkDescriptorSetLayout> m_descriptor_set_layouts;
47+
/// The graphics pipeline setup data which will be std::moved into GraphicsPipeline wrapper
48+
GraphicsPipelineSetupData m_graphics_pipeline_setup_data;
11249

11350
/// Reset all data in this class so the builder can be re-used
114-
/// @note This is called by the constructor
11551
void reset();
11652

11753
public:

src/vulkan-renderer/wrapper/pipelines/graphics_pipeline.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,16 @@ namespace inexor::vulkan_renderer::wrapper::pipelines {
1414
GraphicsPipeline::GraphicsPipeline(const Device &device, const PipelineCache &pipeline_cache,
1515
std::span<const VkDescriptorSetLayout> descriptor_set_layouts,
1616
std::span<const VkPushConstantRange> push_constant_ranges,
17-
VkGraphicsPipelineCreateInfo pipeline_ci, std::string name)
18-
: m_device(device), m_name(std::move(name)) {
17+
GraphicsPipelineSetupData pipeline_setup_data, std::string name)
18+
: m_device(device), m_pipeline_setup_data(std::move(pipeline_setup_data)), m_name(std::move(name)) {
1919

20-
// @TODO Should the pipeline layout really be part of graphics pipeline wrapper?
21-
22-
// Create the graphics pipeline layout
20+
// @TODO Expose the pipeline layout as parameter
2321
m_pipeline_layout = std::make_unique<PipelineLayout>(m_device, m_name, std::move(descriptor_set_layouts),
2422
std::move(push_constant_ranges));
2523

26-
// Set the pipeline layout in the pipeline create info struct
27-
pipeline_ci.layout = m_pipeline_layout->m_pipeline_layout;
24+
const auto pipeline_ci = make_info<VkGraphicsPipelineCreateInfo>({
25+
.layout = m_pipeline_layout->pipeline_layout(),
26+
});
2827

2928
if (const auto result = vkCreateGraphicsPipelines(m_device.device(), pipeline_cache.m_pipeline_cache, 1,
3029
&pipeline_ci, nullptr, &m_pipeline);

src/vulkan-renderer/wrapper/pipelines/graphics_pipeline_builder.cpp

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,8 @@ GraphicsPipelineBuilder::GraphicsPipelineBuilder(const Device &device, const Pip
1717

1818
GraphicsPipelineBuilder::GraphicsPipelineBuilder(GraphicsPipelineBuilder &&other) noexcept
1919
: m_device(other.m_device), m_pipeline_cache(other.m_pipeline_cache) {
20-
// TODO: Check me!
21-
m_pipeline_rendering_ci = std::move(other.m_pipeline_rendering_ci);
22-
m_color_attachments = std::move(other.m_color_attachments);
23-
m_depth_attachment_format = other.m_depth_attachment_format;
24-
m_stencil_attachment_format = other.m_stencil_attachment_format;
25-
m_shader_stages = std::move(other.m_shader_stages);
26-
m_vertex_input_binding_descriptions = std::move(other.m_vertex_input_binding_descriptions);
27-
m_vertex_input_attribute_descriptions = std::move(other.m_vertex_input_attribute_descriptions);
28-
m_vertex_input_sci = std::move(other.m_vertex_input_sci);
29-
m_input_assembly_sci = std::move(other.m_input_assembly_sci);
30-
m_tesselation_sci = std::move(other.m_tesselation_sci);
31-
m_viewport_sci = std::move(other.m_viewport_sci);
32-
m_viewports = std::move(other.m_viewports);
33-
m_scissors = std::move(other.m_scissors);
34-
m_rasterization_sci = std::move(m_rasterization_sci);
35-
m_multisample_sci = std::move(other.m_multisample_sci);
36-
m_depth_stencil_sci = std::move(other.m_depth_stencil_sci);
37-
m_color_blend_sci = std::move(other.m_color_blend_sci);
38-
m_dynamic_states = std::move(other.m_dynamic_states);
39-
m_dynamic_states_sci = std::move(other.m_dynamic_states_sci);
40-
m_pipeline_layout = std::exchange(other.m_pipeline_layout, VK_NULL_HANDLE);
41-
m_color_blend_attachment_states = std::move(other.m_color_blend_attachment_states);
20+
// @TODO: Implement move constructor for GraphicsPipelineSetupData?
21+
m_graphics_pipeline_setup_data = other.m_graphics_pipeline_setup_data;
4222
}
4323

4424
std::shared_ptr<GraphicsPipeline> GraphicsPipelineBuilder::build(std::string name, bool use_dynamic_rendering) {

0 commit comments

Comments
 (0)