Toast Engine
Loading...
Searching...
No Matches
material_pass.hpp
Go to the documentation of this file.
1
6
7#pragma once
8
10#include "../render_pass_base.hpp"
12#include "../shader_layout.hpp"
13#include "../vulkan_pipeline.hpp"
14#include "../vulkan_renderer.hpp"
15
16#include <atomic>
17#include <future>
18#include <memory>
19#include <optional>
20#include <string>
22#include <unordered_map>
23#include <vector>
24
25namespace renderer {
26class VulkanCore;
27
28class MaterialPass : public IRenderPass {
29public:
30 MaterialPass(
31 const VulkanCore& core, assets::Material* root_material, vk::Format color_format, vk::Format depth_format,
32 vk::Extent2D extent
33 );
34
35 [[nodiscard]]
36 auto name() const -> std::string_view override {
37 return m_name;
38 }
39
40 ~MaterialPass() override;
41
42 MaterialPass(const MaterialPass&) = delete;
43 auto operator=(const MaterialPass&) -> MaterialPass& = delete;
44 MaterialPass(MaterialPass&&) = delete;
45 auto operator=(MaterialPass&&) -> MaterialPass& = delete;
46
47 void update(uint32_t frame_index, float dt) override;
48
49 void record(vk::CommandBuffer cmd, uint32_t frame_index, uint32_t image_index) override;
50
51 void recordInstance(vk::CommandBuffer cmd, uint32_t frame_index, const VulkanRenderer::MeshInstanceProxy& proxy);
52
54 void finishPendingBuild();
55
56 [[nodiscard]]
57 auto rootMaterial() const -> assets::Material* {
58 return m_root_material;
59 }
60
62 void markShadersDirty() { m_rebuild_pending.store(true, std::memory_order_release); }
63
64 void markValuesDirty() { m_values_dirty.store(true, std::memory_order_release); }
65
66 [[nodiscard]]
67 auto isValid() const -> bool {
68 return m_built != nullptr;
69 }
70
71 [[nodiscard]]
72 auto usesCutout() const noexcept -> bool {
73 return m_built != nullptr && m_built->uses_cutout;
74 }
75
76 [[nodiscard]]
77 auto isBlended() const -> bool {
78 return m_root_material != nullptr && m_root_material->settings().blend_mode != assets::BlendMode::opaque;
79 }
80
81private:
82 [[nodiscard]]
83 static auto resolvedAlphaCutoffOf(MaterialRuntime& runtime) -> float;
84
85 struct InstanceResources {
86 std::unique_ptr<MaterialRuntime> runtime;
87
88 struct UboBuffer {
89 uint32_t set = 0;
90 uint32_t binding = 0;
91 std::vector<std::optional<vma::raii::Buffer>> buffers;
92 };
93
94 std::vector<UboBuffer> ubo_buffers;
95 std::vector<std::vector<vk::raii::DescriptorSet>> sets;
96
98 struct BoundView {
99 vk::ImageView view;
100 uint64_t generation = 0;
101
102 auto operator==(const BoundView&) const -> bool = default;
103 };
104
105 std::vector<std::vector<BoundView>> bound_views;
106 };
107
108 struct Built {
109 Built(const VulkanCore& core, assets::Material* material) : runtime(core, material) { }
110
111 MaterialRuntime runtime;
112 ShaderLayout layout;
113 VulkanPipeline pipeline;
114 bool uses_cutout = false;
115
117 SceneDescriptorSets scene_sets;
118 std::unordered_map<assets::Material*, InstanceResources> instances;
119 };
120
122 struct BuildInputs {
123 const VulkanCore* core = nullptr;
124 assets::Material* root_material = nullptr;
125 std::string name;
126 vk::Format color_format = vk::Format::eUndefined;
127 vk::Format depth_format = vk::Format::eUndefined;
128 vk::Extent2D extent;
129 };
130
132 static auto build(const BuildInputs& inputs) -> std::shared_ptr<Built>;
133 void startBuild();
134 void adopt(std::shared_ptr<Built> built);
135
136 void drawInstance(
137 Built& built, vk::CommandBuffer cmd, uint32_t frame_index, const VulkanRenderer::MeshInstanceProxy& proxy,
138 vk::Buffer posed_vertices, uint32_t posed_vertex_offset, assets::Material** bound_material, uint32_t instance_count = 1
139 );
140
141 auto ensureInstanceResources(Built& built, assets::Material* material) -> InstanceResources*;
142 void updateInstanceDescriptors(InstanceResources& res, uint32_t frame_index);
143
144 const VulkanCore* m_core = nullptr;
145 assets::Material* m_root_material = nullptr;
146
147 assets::Handle<assets::Material> m_root_material_ref;
148 std::string m_name;
149
150 vk::Format m_color_format = vk::Format::eUndefined;
151 vk::Format m_depth_format = vk::Format::eUndefined;
152 vk::Extent2D m_extent;
153
155 std::shared_ptr<Built> m_built;
156 std::future<std::shared_ptr<Built>> m_pending_build;
157
158 std::vector<std::byte> m_push_scratch;
159 std::vector<uint32_t> m_draw_order;
160
161 std::atomic_bool m_rebuild_pending {false};
162 std::atomic_bool m_values_dirty {false};
163};
164
165}
Definition render_pass_base.hpp:19
Shader-driven material asset.
Definition material.hpp:49
void finishPendingBuild()
Render thread and blocks on a running build for frames such as probe captures.
Definition material_pass.cpp:272
void markShadersDirty()
Any thread and the old pipeline draws until the new one is built.
Definition material_pass.hpp:62
Definition material_runtime.hpp:24
Definition scene_descriptor_set.hpp:22
Definition shader_layout.hpp:12
Definition vulkan_core.hpp:48
Definition vulkan_pipeline.hpp:19
Material asset backed by TOML data.
View plus texture generation since a recreated view can reuse a destroyed handle value.
Definition material_pass.hpp:98
Definition vulkan_renderer.hpp:262