Midnight Graphics
Create Fast and Simple Graphics in C++
Pipeline.hpp
1 #pragma once
2 
3 #include "Backend/Device.hpp"
4 #include "Buffer.hpp"
5 #include "ObjectHandle.hpp"
6 #include "Image.hpp"
7 
8 #include "Descriptor.hpp"
9 
10 #include <unordered_map>
11 #include <vector>
12 #include <filesystem>
13 
14 namespace mn::Graphics
15 {
16  struct Image;
17  struct Pipeline;
18 
19  enum class ShaderType
20  {
21  None, Vertex, Fragment, Compute
22  };
23 
24  enum class Topology
25  {
26  Triangles, Lines
27  };
28 
29  enum class Polygon
30  {
31  Fill, Wireframe
32  };
33 
34  struct Shader : ObjectHandle<Shader>
35  {
36  friend struct Pipeline;
37 
38  struct Attribute
39  {
40  u32 element_count, element_size, format;
41  u8 binding = 0;
42  };
43 
44  MN_SYMBOL Shader();
45  MN_SYMBOL Shader(std::filesystem::path path, ShaderType type);
46  MN_SYMBOL ~Shader();
47 
48  MN_SYMBOL void fromFile(std::filesystem::path path, ShaderType type);
49  MN_SYMBOL void fromString(const std::string& contents, ShaderType type, const std::string& path = "");
50  MN_SYMBOL void fromSpv(const std::vector<uint32_t>& contents, ShaderType type);
51 
52  auto getType() const { return type; }
53 
54  const auto& getAttributes() const { MIDNIGHT_ASSERT(type == ShaderType::Vertex, "Attributes only for vertex shader"); return *attributes; }
55 
56  private:
57  ShaderType type;
58  std::optional<std::vector<Attribute>> attributes;
59  };
60 
61  struct PipelineBuilder;
62 
63  struct Pipeline : ObjectHandle<Pipeline>
64  {
65  friend struct PipelineBuilder;
66 
67  Pipeline(const Pipeline&) = delete;
68  Pipeline(Pipeline&&);
69 
70  MN_SYMBOL ~Pipeline();
71 
72  auto getBindingStride() const { return binding_strides[0]; }
73 
74  MN_SYMBOL void setPushConstant(const std::unique_ptr<Backend::CommandBuffer>& cmd, const void* data) const;
75 
76  template<typename T>
77  void setPushConstant(const std::unique_ptr<Backend::CommandBuffer>& cmd, const T& value) const
78  {
79  MIDNIGHT_ASSERT(sizeof(T) == push_constant_size, "Push constant size descrepancy");
80  setPushConstant(cmd, reinterpret_cast<const void*>(&value));
81  }
82 
83  auto getLayoutHandle() const { return layout; }
84  const auto& getDescriptorLayouts() const { return descriptor_layouts; }
85 
86  private:
88 
89  uint32_t push_constant_size;
90  std::vector<std::shared_ptr<Descriptor::Layout>> descriptor_layouts;
91  std::vector<uint32_t> binding_strides;
92  mn::handle_t layout;
93  };
94 
96  {
97 
98  MN_SYMBOL static PipelineBuilder fromLua(const std::string& source_dir, const std::string& script);
99 
100  MN_SYMBOL PipelineBuilder& addShader(std::filesystem::path path, ShaderType type);
101  MN_SYMBOL PipelineBuilder& addShader(std::shared_ptr<Shader> shader);
102  MN_SYMBOL PipelineBuilder& setPolyMode(Polygon p);
103  MN_SYMBOL PipelineBuilder& setTopology(Topology t);
104  MN_SYMBOL PipelineBuilder& setBackfaceCull(bool cull);
105  MN_SYMBOL PipelineBuilder& setBlending(bool blend);
106  MN_SYMBOL PipelineBuilder& setDepthTesting(bool d);
107  MN_SYMBOL PipelineBuilder& setCullDirection(bool clockwise);
108  MN_SYMBOL PipelineBuilder& setSize(uint32_t w, uint32_t h);
109  MN_SYMBOL PipelineBuilder& setDepthFormat(uint32_t d);
110  MN_SYMBOL PipelineBuilder& addDescriptorLayout(std::shared_ptr<Descriptor::Layout> d);
111  MN_SYMBOL PipelineBuilder& addAttachmentFormat(Image::Format format);
112 
113  // We want to be able to create a global descriptor set, then pass it into each
114  // of our pipelines... So the descriptor creation really *shouldn't* be here
115  //MN_SYMBOL PipelineBuilder& addTextureBinding();
116 
117  template<typename T>
118  PipelineBuilder& setPushConstantObject()
119  {
120  push_constant_size = sizeof(T);
121  return *this;
122  }
123 
124  [[nodiscard]] MN_SYMBOL Pipeline build() const;
125 
126  PipelineBuilder() = default;
127  PipelineBuilder(const PipelineBuilder&) = default;
128  PipelineBuilder(PipelineBuilder&&) = default;
129 
130  private:
131  std::vector<uint32_t> attachment_formats;
132  std::vector<std::shared_ptr<Descriptor::Layout>> descriptor_layouts;
133  std::pair<uint32_t, uint32_t> size;
134  std::unordered_map<ShaderType, std::shared_ptr<Shader>> modules;
135  Topology top = Topology::Triangles;
136  Polygon poly = Polygon::Fill;
137  bool backface_cull = true, blending = true, depth = true, clockwise = true;
138  uint32_t depth_format = 0, push_constant_size = 0;
139  };
140 }
Definition: ObjectHandle.hpp:9
Definition: Pipeline.hpp:96
Definition: Pipeline.hpp:64
Definition: Pipeline.hpp:39
Definition: Pipeline.hpp:35
Definition: TypedHandle.hpp:9