Skip to content

Commit 883b2ba

Browse files
committed
WIP
1 parent 841423a commit 883b2ba

File tree

7 files changed

+179
-5
lines changed

7 files changed

+179
-5
lines changed

guide/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@
2727
- [Graphics Pipeline](pipeline/README.md)
2828
- [Locating Assets](pipeline/locating_assets.md)
2929
- [Shaders](pipeline/shaders.md)
30+
- [Pipeline Creation](pipeline/creation.md)

guide/src/pipeline/creation.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Pipeline Creation

src/app.cpp

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ void App::run(std::string_view const assets_dir) {
4040
create_swapchain();
4141
create_render_sync();
4242
create_imgui();
43+
create_pipeline_builder();
4344

4445
create_pipeline();
4546

@@ -177,8 +178,13 @@ void App::create_imgui() {
177178
m_imgui.emplace(imgui_ci);
178179
}
179180

180-
auto App::asset_path(std::string_view const uri) const -> fs::path {
181-
return m_assets_dir / uri;
181+
void App::create_pipeline_builder() {
182+
auto const pipeline_builder_ci = PipelineBuilder::CreateInfo{
183+
.device = *m_device,
184+
.samples = vk::SampleCountFlagBits::e1,
185+
.color_format = m_swapchain->get_format(),
186+
};
187+
m_pipeline_builder.emplace(pipeline_builder_ci);
182188
}
183189

184190
void App::create_pipeline() {
@@ -192,7 +198,19 @@ void App::create_pipeline() {
192198
}
193199
std::println("[lvk] Shaders loaded");
194200

195-
// TODO
201+
m_pipeline_layout = m_device->createPipelineLayoutUnique({});
202+
auto const pipeline_state = PipelineState{
203+
.vertex_shader = *vertex,
204+
.fragment_shader = *fragment,
205+
};
206+
m_pipeline = m_pipeline_builder->build(*m_pipeline_layout, pipeline_state);
207+
if (!m_pipeline) {
208+
throw std::runtime_error{"Failed to create Graphics Pipeline"};
209+
}
210+
}
211+
212+
auto App::asset_path(std::string_view const uri) const -> fs::path {
213+
return m_assets_dir / uri;
196214
}
197215

198216
void App::main_loop() {
@@ -282,7 +300,15 @@ void App::render(vk::CommandBuffer const command_buffer) {
282300

283301
command_buffer.beginRendering(rendering_info);
284302
ImGui::ShowDemoWindow();
285-
// draw stuff here.
303+
command_buffer.bindPipeline(vk::PipelineBindPoint::eGraphics, *m_pipeline);
304+
auto viewport = vk::Viewport{};
305+
viewport.setX(0.0f)
306+
.setY(static_cast<float>(m_render_target->extent.height))
307+
.setWidth(static_cast<float>(m_render_target->extent.width))
308+
.setHeight(-viewport.y);
309+
command_buffer.setViewport(0, viewport);
310+
command_buffer.setScissor(0, render_area);
311+
command_buffer.draw(3, 1, 0, 0);
286312
command_buffer.endRendering();
287313

288314
m_imgui->end_frame();

src/app.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
#pragma once
22
#include <dear_imgui.hpp>
33
#include <gpu.hpp>
4+
#include <pipeline_builder.hpp>
45
#include <resource_buffering.hpp>
56
#include <scoped_waiter.hpp>
67
#include <swapchain.hpp>
7-
#include <vulkan/vulkan.hpp>
88
#include <window.hpp>
99
#include <filesystem>
1010

@@ -35,6 +35,7 @@ class App {
3535
void create_swapchain();
3636
void create_render_sync();
3737
void create_imgui();
38+
void create_pipeline_builder();
3839
void create_pipeline();
3940

4041
[[nodiscard]] auto asset_path(std::string_view uri) const -> fs::path;
@@ -67,6 +68,10 @@ class App {
6768
std::size_t m_frame_index{};
6869

6970
std::optional<DearImGui> m_imgui{};
71+
std::optional<PipelineBuilder> m_pipeline_builder{};
72+
73+
vk::UniquePipelineLayout m_pipeline_layout{};
74+
vk::UniquePipeline m_pipeline{};
7075

7176
glm::ivec2 m_framebuffer_size{};
7277
std::optional<RenderTarget> m_render_target{};

src/pipeline_builder.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include <pipeline_builder.hpp>
2+
3+
namespace lvk {
4+
PipelineBuilder::PipelineBuilder(CreateInfo const& create_info)
5+
: m_info(create_info) {}
6+
7+
auto PipelineBuilder::build(vk::PipelineLayout const layout,
8+
PipelineState const& state) const
9+
-> vk::UniquePipeline {
10+
auto shader_stages = std::array<vk::PipelineShaderStageCreateInfo, 2>{};
11+
shader_stages[0]
12+
.setStage(vk::ShaderStageFlagBits::eVertex)
13+
.setPName("main")
14+
.setModule(state.vertex_shader);
15+
shader_stages[1]
16+
.setStage(vk::ShaderStageFlagBits::eFragment)
17+
.setPName("main")
18+
.setModule(state.fragment_shader);
19+
20+
auto prsci = vk::PipelineRasterizationStateCreateInfo{};
21+
prsci.setPolygonMode(state.polygon_mode).setCullMode(state.cull_mode);
22+
23+
auto pdssci = vk::PipelineDepthStencilStateCreateInfo{};
24+
auto const depth_test =
25+
(state.flags & PipelineFlag::DepthTest) == PipelineFlag::DepthTest;
26+
pdssci.setDepthTestEnable(depth_test ? vk::True : vk::False)
27+
.setDepthCompareOp(state.depth_compare);
28+
29+
auto const piasci =
30+
vk::PipelineInputAssemblyStateCreateInfo{{}, state.topology};
31+
32+
auto pcbas = vk::PipelineColorBlendAttachmentState{};
33+
auto const alpha_blend =
34+
(state.flags & PipelineFlag::AlphaBlend) == PipelineFlag::AlphaBlend;
35+
using CCF = vk::ColorComponentFlagBits;
36+
pcbas.setColorWriteMask(CCF::eR | CCF::eG | CCF::eB | CCF::eA)
37+
.setBlendEnable(alpha_blend ? vk::True : vk::False)
38+
.setSrcColorBlendFactor(vk::BlendFactor::eSrcAlpha)
39+
.setDstColorBlendFactor(vk::BlendFactor::eOneMinusSrcAlpha)
40+
.setColorBlendOp(vk::BlendOp::eAdd)
41+
.setSrcAlphaBlendFactor(vk::BlendFactor::eOne)
42+
.setDstAlphaBlendFactor(vk::BlendFactor::eZero)
43+
.setAlphaBlendOp(vk::BlendOp::eAdd);
44+
auto pcbsci = vk::PipelineColorBlendStateCreateInfo{};
45+
pcbsci.setAttachments(pcbas);
46+
47+
auto const pdscis = std::array{
48+
vk::DynamicState::eViewport,
49+
vk::DynamicState::eScissor,
50+
vk::DynamicState::eLineWidth,
51+
};
52+
auto pdsci = vk::PipelineDynamicStateCreateInfo{};
53+
pdsci.setDynamicStates(pdscis);
54+
55+
auto const pvsci = vk::PipelineViewportStateCreateInfo({}, 1, {}, 1);
56+
57+
auto pmsci = vk::PipelineMultisampleStateCreateInfo{};
58+
pmsci.setRasterizationSamples(m_info.samples)
59+
.setSampleShadingEnable(vk::False);
60+
61+
auto prci = vk::PipelineRenderingCreateInfo{};
62+
if (m_info.color_format != vk::Format::eUndefined) {
63+
prci.setColorAttachmentFormats(m_info.color_format);
64+
}
65+
prci.setDepthAttachmentFormat(m_info.depth_format);
66+
67+
auto gpci = vk::GraphicsPipelineCreateInfo{};
68+
gpci.setStages(shader_stages)
69+
.setPRasterizationState(&prsci)
70+
.setPDepthStencilState(&pdssci)
71+
.setPInputAssemblyState(&piasci)
72+
.setPColorBlendState(&pcbsci)
73+
.setPDynamicState(&pdsci)
74+
.setPViewportState(&pvsci)
75+
.setPMultisampleState(&pmsci)
76+
.setLayout(layout)
77+
.setPNext(&prci);
78+
79+
auto ret = vk::Pipeline{};
80+
if (m_info.device.createGraphicsPipelines({}, 1, &gpci, {}, &ret) !=
81+
vk::Result::eSuccess) {
82+
return {};
83+
}
84+
85+
return vk::UniquePipeline{ret, m_info.device};
86+
}
87+
} // namespace lvk

src/pipeline_builder.hpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#pragma once
2+
#include <pipeline_state.hpp>
3+
4+
namespace lvk {
5+
struct PipelineBuilderCreateInfo {
6+
vk::Device device{};
7+
vk::SampleCountFlagBits samples{};
8+
vk::Format color_format{};
9+
vk::Format depth_format{};
10+
};
11+
12+
class PipelineBuilder {
13+
public:
14+
using CreateInfo = PipelineBuilderCreateInfo;
15+
16+
explicit PipelineBuilder(CreateInfo const& create_info);
17+
18+
[[nodiscard]] auto build(vk::PipelineLayout layout,
19+
PipelineState const& state) const
20+
-> vk::UniquePipeline;
21+
22+
private:
23+
CreateInfo m_info{};
24+
};
25+
} // namespace lvk

src/pipeline_state.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
#include <vulkan/vulkan.hpp>
3+
4+
namespace lvk {
5+
struct PipelineFlag {
6+
enum : std::uint8_t {
7+
None = 0,
8+
AlphaBlend = 1 << 0,
9+
DepthTest = 1 << 1,
10+
};
11+
};
12+
13+
struct PipelineState {
14+
using Flag = PipelineFlag;
15+
16+
[[nodiscard]] static constexpr auto default_flags() -> std::uint8_t {
17+
return Flag::AlphaBlend | Flag::DepthTest;
18+
}
19+
20+
vk::ShaderModule vertex_shader;
21+
vk::ShaderModule fragment_shader;
22+
23+
vk::PrimitiveTopology topology{vk::PrimitiveTopology::eTriangleList};
24+
vk::PolygonMode polygon_mode{vk::PolygonMode::eFill};
25+
vk::CullModeFlags cull_mode{vk::CullModeFlagBits::eNone};
26+
vk::CompareOp depth_compare{vk::CompareOp::eLess};
27+
std::uint8_t flags{default_flags()};
28+
};
29+
} // namespace lvk

0 commit comments

Comments
 (0)