Blender V5.0
vk_resource_state_tracker.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_index_range.hh"
10
12
14
15/* -------------------------------------------------------------------- */
18ResourceHandle VKResourceStateTracker::create_resource_slot()
19{
20 ResourceHandle handle;
21 if (unused_handles_.is_empty()) {
22 handle = resources_.size();
23 }
24 else {
25 handle = unused_handles_.pop_last();
26 }
27
28 Resource new_resource = {};
29 resources_.add_new(handle, new_resource);
30 return handle;
31}
32
33void VKResourceStateTracker::add_image(VkImage vk_image,
34 bool use_subresource_tracking,
35 VKResourceBarrierState barrier_state,
36 const char *name)
37{
39 BLI_assert_msg(!image_resources_.contains(vk_image),
40 "Image resource is added twice to the render graph.");
41 std::scoped_lock lock(mutex);
42 ResourceHandle handle = create_resource_slot();
43 Resource &resource = resources_.lookup(handle);
44 image_resources_.add_new(vk_image, handle);
45
47 resource.image.vk_image = vk_image;
48 resource.image.use_subresource_tracking = use_subresource_tracking;
49 resource.barrier_state = barrier_state;
50#ifndef NDEBUG
51 resource.name = name;
52#endif
53
54#ifdef VK_RESOURCE_STATE_TRACKER_VALIDATION
55 validate();
56#endif
57}
58
60 bool use_subresource_tracking,
61 const char *name)
62{
63 add_image(vk_image, use_subresource_tracking, {}, name);
64}
65
66void VKResourceStateTracker::add_swapchain_image(VkImage vk_image, const char *name)
67{
68 add_image(vk_image,
69 false,
70 {
71 VK_ACCESS_NONE,
72 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
73 },
74 name);
75}
76
77void VKResourceStateTracker::add_buffer(VkBuffer vk_buffer, const char *name)
78{
80 BLI_assert_msg(!buffer_resources_.contains(vk_buffer),
81 "Buffer resource is added twice to the render graph.");
82 std::scoped_lock lock(mutex);
83 ResourceHandle handle = create_resource_slot();
84 Resource &resource = resources_.lookup(handle);
85 buffer_resources_.add_new(vk_buffer, handle);
86
88 resource.buffer.vk_buffer = vk_buffer;
89 resource.stamp = 0;
90#ifndef NDEBUG
91 resource.name = name;
92#endif
93
94#ifdef VK_RESOURCE_STATE_TRACKER_VALIDATION
95 validate();
96#endif
97}
98
100
101/* -------------------------------------------------------------------- */
104
106{
107 std::scoped_lock lock(mutex);
108 ResourceHandle handle = buffer_resources_.pop(vk_buffer);
109 resources_.pop(handle);
110 unused_handles_.append(handle);
111
112#ifdef VK_RESOURCE_STATE_TRACKER_VALIDATION
113 validate();
114#endif
115}
116
118{
119 std::scoped_lock lock(mutex);
120 ResourceHandle handle = image_resources_.pop(vk_image);
121 resources_.pop(handle);
122 unused_handles_.append(handle);
123
124#ifdef VK_RESOURCE_STATE_TRACKER_VALIDATION
125 validate();
126#endif
127}
128
130
131ResourceWithStamp VKResourceStateTracker::get_stamp(ResourceHandle handle,
132 const Resource &resource)
133{
135 result.handle = handle;
136 result.stamp = resource.stamp;
137 return result;
138}
139
140ResourceWithStamp VKResourceStateTracker::get_and_increase_stamp(ResourceHandle handle,
141 Resource &resource)
142{
143 ResourceWithStamp result = get_stamp(handle, resource);
144 resource.stamp += 1;
145 return result;
146}
147
149{
150 ResourceHandle handle = image_resources_.lookup(vk_image);
151 Resource &resource = resources_.lookup(handle);
152 return get_and_increase_stamp(handle, resource);
153}
154
156{
157 ResourceHandle handle = buffer_resources_.lookup(vk_buffer);
158 Resource &resource = resources_.lookup(handle);
159 return get_and_increase_stamp(handle, resource);
160}
161
163{
164 ResourceHandle handle = buffer_resources_.lookup(vk_buffer);
165 const Resource &resource = resources_.lookup(handle);
166 return get_stamp(handle, resource);
167}
168
170{
171 ResourceHandle handle = image_resources_.lookup(vk_image);
172 const Resource &resource = resources_.lookup(handle);
173 return get_stamp(handle, resource);
174}
175
176#ifdef VK_RESOURCE_STATE_TRACKER_VALIDATION
177void VKResourceStateTracker::validate() const
178{
179 for (const Map<VkImage, ResourceHandle>::Item &item : image_resources_.items()) {
180 for (ResourceHandle buffer_handle : buffer_resources_.values()) {
181 BLI_assert(item.value != buffer_handle);
182 }
183 BLI_assert(resources_.contains(item.value));
184 const Resource &resource = resources_.lookup(item.value);
186 }
187
188 for (const Map<VkBuffer, ResourceHandle>::Item &item : buffer_resources_.items()) {
189 for (ResourceHandle image_handle : image_resources_.values()) {
190 BLI_assert(item.value != image_handle);
191 }
192 BLI_assert(resources_.contains(item.value));
193 const Resource &resource = resources_.lookup(item.value);
195 }
196
197 BLI_assert(resources_.size() == image_resources_.size() + buffer_resources_.size());
198}
199#endif
200
202{
203 std::ostream &os = std::cout;
204 os << "VKResourceStateTracker\n";
205 os << " resources=(" << resources_.size() << "/" << resources_.capacity() << ")\n";
206 os << " buffers=(" << buffer_resources_.size() << "/" << buffer_resources_.capacity() << ")\n";
207 os << " images=(" << image_resources_.size() << "/" << image_resources_.capacity() << ")\n";
208 os << " unused=(" << unused_handles_.size() << "/" << unused_handles_.capacity() << ")\n";
209}
210
211} // namespace blender::gpu::render_graph
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
#define UNUSED_VARS_NDEBUG(...)
volatile int lock
ValueIterator values() const &
Definition BLI_map.hh:884
const Value & lookup(const Key &key) const
Definition BLI_map.hh:545
bool contains(const Key &key) const
Definition BLI_map.hh:353
ItemIterator items() const &
Definition BLI_map.hh:902
MapItem< Key, Value > Item
Definition BLI_map.hh:132
ResourceWithStamp get_image_and_increase_stamp(VkImage vk_image)
ResourceWithStamp get_buffer_and_increase_stamp(VkBuffer vk_buffer)
void add_image(VkImage vk_image, bool use_subresource_tracking, const char *name=nullptr)
ResourceWithStamp get_buffer(VkBuffer vk_buffer) const
void add_buffer(VkBuffer vk_buffer, const char *name=nullptr)
void add_swapchain_image(VkImage vk_image, const char *name=nullptr)
ResourceWithStamp get_image(VkImage vk_image) const
#define resource
const char * name