MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
TextureBindingsProcessor.cpp
Go to the documentation of this file.
2
5
7
8namespace MayaFlux::Buffers {
9
11 const std::string& name,
12 const std::shared_ptr<Nodes::GpuSync::TextureNode>& node,
13 const std::shared_ptr<VKBuffer>& texture)
14{
15 if (!node) {
16 error<std::invalid_argument>(
19 std::source_location::current(),
20 "Cannot bind null texture node '{}'", name);
21 }
22
23 if (!texture) {
24 error<std::invalid_argument>(
27 std::source_location::current(),
28 "Cannot bind texture node '{}' to null texture buffer", name);
29 }
30
31 size_t texture_size = static_cast<size_t>(node->get_width()) * static_cast<size_t>(node->get_height()) * 4 * sizeof(float);
32
33 if (texture->get_size_bytes() < texture_size) {
34 error<std::invalid_argument>(
37 std::source_location::current(),
38 "Texture buffer for '{}' is too small: {} bytes required, {} available",
39 name, texture_size, texture->get_size_bytes());
40 }
41
42 std::shared_ptr<VKBuffer> staging = nullptr;
43 if (!texture->is_host_visible()) {
44 staging = create_staging_buffer(texture_size);
45
47 "Created staging buffer for device-local texture '{}' ({} bytes)",
48 name, texture_size);
49 } else {
51 "No staging needed for host-visible texture '{}'", name);
52 }
53
55 .node = node,
56 .gpu_texture = texture,
57 .staging_buffer = staging
58 };
59
61 "Bound texture node '{}' ({}x{}, {} bytes)",
62 name, node->get_width(), node->get_height(), texture_size);
63}
64
66{
67 if (m_bindings.erase(name) == 0) {
69 "Attempted to unbind non-existent texture node '{}'", name);
70 } else {
72 "Unbound texture node '{}'", name);
73 }
74}
75
76std::vector<std::string> TextureBindingsProcessor::get_binding_names() const
77{
78 std::vector<std::string> names;
79 names.reserve(m_bindings.size());
80 for (const auto& [name, _] : m_bindings) {
81 names.push_back(name);
82 }
83 return names;
84}
85
86void TextureBindingsProcessor::processing_function(std::shared_ptr<Buffer> buffer)
87{
88 if (m_bindings.empty()) {
89 return;
90 }
91
92 auto vk_buffer = std::dynamic_pointer_cast<VKBuffer>(buffer);
93 if (!vk_buffer) {
95 "TextureBindingsProcessor requires VKBuffer, got different buffer type");
96 return;
97 }
98
99 bool attached_is_host_visible = vk_buffer->is_host_visible();
100
101 for (auto& [name, binding] : m_bindings) {
102 if (!binding.node->needs_gpu_update()) {
104 "Texture '{}' unchanged, skipping upload", name);
105 continue;
106 }
107
108 auto pixels = binding.node->get_pixel_buffer();
109
110 if (pixels.empty()) {
112 "Texture node '{}' has empty pixel buffer, skipping upload", name);
113 continue;
114 }
115
117 pixels.data(),
118 pixels.size_bytes(),
119 binding.gpu_texture,
120 binding.staging_buffer);
121
122 binding.node->clear_gpu_update_flag();
123 }
124
125 if (!m_bindings.empty()) {
126 auto& first_binding = m_bindings.begin()->second;
127
128 bool attached_is_target = false;
129 for (const auto& [name, binding] : m_bindings) {
130 if (binding.gpu_texture == vk_buffer) {
131 attached_is_target = true;
132 break;
133 }
134 }
135
136 if (!attached_is_target) {
137 auto pixels = first_binding.node->get_pixel_buffer();
138
139 if (!pixels.empty()) {
140 std::shared_ptr<VKBuffer> staging = attached_is_host_visible ? nullptr : first_binding.staging_buffer;
141
143 pixels.data(),
144 pixels.size_bytes(),
145 vk_buffer,
146 staging);
147 }
148 }
149 }
150}
151
152} // namespace MayaFlux::Buffers
#define MF_RT_WARN(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_TRACE(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
void bind_texture_node(const std::string &name, const std::shared_ptr< Nodes::GpuSync::TextureNode > &node, const std::shared_ptr< VKBuffer > &texture)
Bind a texture node to a GPU texture buffer.
void unbind_texture_node(const std::string &name)
Remove a texture binding.
std::vector< std::string > get_binding_names() const
Get all binding names.
void processing_function(std::shared_ptr< Buffer > buffer) override
The core processing function that must be implemented by derived classes.
std::unordered_map< std::string, TextureBinding > m_bindings
std::shared_ptr< VKBuffer > create_staging_buffer(size_t size)
Create staging buffer for transfers.
void upload_to_gpu(const void *data, size_t size, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging)
Upload raw data to GPU buffer (auto-detects host-visible vs device-local)
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.