Midnight Graphics
Create Fast and Simple Graphics in C++
Descriptor.hpp
1 #pragma once
2 
3 #include "ObjectHandle.hpp"
4 
5 namespace mn::Graphics
6 {
7  struct Image;
8 
9 namespace Backend
10 {
11  struct Sampler;
12 }
13 
14  struct DescriptorLayoutBuilder;
15 
16  // Basic abstraction of vulkan descriptor set
17  // We should have pools built *out* as well, but for now each
18  // set has its own pool (bad)
19  struct Descriptor : ObjectHandle<Descriptor>
20  {
21  struct Layout : ObjectHandle<Layout>
22  {
23  struct Binding
24  {
25  enum Type
26  {
27  Image, Sampler
28  } type;
29 
30  uint32_t count;
31  };
32 
33  Layout(Layout&& l);
34  Layout(const Layout&) = delete;
35  ~Layout();
36 
37  template<Binding::Type T>
38  struct BindingData;
39 
40  bool hasVariableBinding() const { return variable_binding.has_value(); }
41  const auto& getVariableBinding() const { return *variable_binding; }
42 
43  const auto& getBindings() const { return bindings; }
44 
45  friend struct DescriptorLayoutBuilder;
46 
47  private:
48  Layout() = default;
49 
50  std::optional<Binding> variable_binding;
51  std::vector<Binding> bindings;
52  };
53 
54  struct Pool : ObjectHandle<Pool>, std::enable_shared_from_this<Pool>
55  {
56  ~Pool();
57 
58  Pool(const Pool&) = delete;
59  Pool(Pool&&);
60 
61  std::shared_ptr<Descriptor>
62  allocateDescriptor(std::shared_ptr<Layout> layout);
63 
64  static std::shared_ptr<Pool> make()
65  {
66  return std::shared_ptr<Pool>(new Pool());
67  }
68 
69  private:
70  Pool();
71  };
72 
73  Descriptor(const Descriptor&) = delete;
75 
76  ~Descriptor() = default;
77 
78  // If there's a 1:1 mapping of type -> index, we don't need to pass in index
79  template<Layout::Binding::Type T>
80  void update(uint32_t index, const typename Layout::BindingData<T>::Type& data);
81 
82  auto getLayoutHandle() const { return layout; }
83 
84  friend struct Pool;
85 
86  private:
87 
88  Descriptor() = default;
89 
90  // Binding index -> Descriptor::Binding::Type
91  //std::unordered_map<uint32_t, Binding::Type> binding_types;
92 
93  std::shared_ptr<Layout> layout;
94  std::shared_ptr<Pool> pool;
95  };
96 
97  template<>
98  struct Descriptor::Layout::BindingData<Descriptor::Layout::Binding::Image>
99  {
100  using Type = std::vector<std::shared_ptr<Image>>;
101  };
102 
103  template<>
104  struct Descriptor::Layout::BindingData<Descriptor::Layout::Binding::Sampler>
105  {
106  using Type = std::vector<std::shared_ptr<Backend::Sampler>>;
107  };
108 
110  {
111  MN_SYMBOL DescriptorLayoutBuilder& addBinding(Descriptor::Layout::Binding binding);
112  MN_SYMBOL DescriptorLayoutBuilder& addVariableBinding(Descriptor::Layout::Binding::Type binding, uint32_t max_size);
113 
114  MN_SYMBOL [[nodiscard]] Descriptor::Layout build() const;
115 
116  private:
117  std::optional<Descriptor::Layout::Binding> variable_binding;
118  std::vector<Descriptor::Layout::Binding> bindings;
119  };
120 }
Definition: Descriptor.hpp:110
Definition: Descriptor.hpp:24
Definition: Descriptor.hpp:22
Definition: Descriptor.hpp:55
Definition: Descriptor.hpp:20
Definition: Image.hpp:14
Definition: ObjectHandle.hpp:9