chrono_batch_render/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
13 / 13
100.0%
Branches:
14 / 14
100.0%
Functions:
-
-%

texture/cache.h
Line Branch Exec Source
1 // SPDX-License-Identifier: BSD-3-Clause
2 #pragma once
3
4 #include <array>
5 #include <condition_variable>
6 #include <cstddef>
7 #include <cstdint>
8 #include <functional>
9 #include <map>
10 #include <memory>
11 #include <mutex>
12 #include <optional>
13 #include <set>
14 #include <string>
15 #include <string_view>
16 #include <utility>
17 #include <vector>
18
19 #include "chrono_batch_render/device/buffer.h"
20 #include "chrono_batch_render/device/device.h"
21 #include "chrono_batch_render/device/kernels/texture.h"
22 #include "chrono_batch_render/device/program.h"
23 #include "chrono_batch_render/device/ref.h"
24 #include "chrono_batch_render/device/texture.h"
25 #include "chrono_batch_render/texture/kernels/mips.h"
26 #include "chrono_batch_render/util/thread_pool.h"
27
28 namespace chrono::batch_render {
29
30 using FileBytes = std::shared_ptr<const std::vector<std::byte>>;
31 using FileLookup = std::function<FileBytes(const std::string& path)>;
32 using TextureKey = std::pair<std::string, bool>;
33
34 inline constexpr std::string_view kCheckerboardTexture = "<checkerboard>";
35
36
2/2
✓ Branch 3 taken 124 times.
✓ Branch 20 taken 360 times.
1156 struct TextureBinding {
37 TextureKey key;
38 TextureWrap wrapS = TextureWrap::Repeat;
39 TextureWrap wrapT = TextureWrap::Repeat;
40 uint32_t desc = ~0u;
41 uint64_t handle = 0;
42 };
43
44 class TextureCache {
45 public:
46 TextureCache(device::Device& device, FileLookup files, unsigned threads);
47 ~TextureCache();
48 TextureCache(const TextureCache&) = delete;
49 TextureCache& operator=(const TextureCache&) = delete;
50
51 TextureBinding Bind(TextureKey key, TextureWrap wrapS, TextureWrap wrapT);
52 void Resolve(TextureBinding& binding);
53 void Unbind(const TextureBinding& binding);
54
55 std::set<TextureKey> Collect();
56 bool Pending() const;
57 void Finish();
58
59 std::optional<std::pair<uint32_t, uint32_t>> Size(const TextureKey& key) const;
60
61 506 uint32_t Images() const {
62
5/5
✓ Branch 1 taken 501 times.
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
✓ Branch 7 taken 1 time.
✓ Branch 10 taken 2 times.
506 return uint32_t(m_images.size());
63 }
64
65 uint32_t Loading() const;
66
67 501 uint32_t Loaded() const {
68
1/1
✓ Branch 1 taken 501 times.
501 return m_loaded;
69 }
70
71 504 uint32_t Failed() const {
72
3/3
✓ Branch 1 taken 1 time.
✓ Branch 1 taken 501 times.
✓ Branch 4 taken 2 times.
504 return m_failed;
73 }
74
75 uint32_t AllocateBindings(uint32_t count);
76 void FreeBindings(uint32_t start, uint32_t count);
77 void SetBinding(uint32_t index, uint64_t handle);
78
79 3 uint64_t Binding(uint32_t index) const {
80
2/2
✓ Branch 1 taken 1 time.
✓ Branch 4 taken 1 time.
3 return m_bindings[index];
81 }
82
83 uint64_t UploadBindings();
84
85 private:
86
1/1
✓ Branch 8 taken 40 times.
128 struct Decoded {
87 uint32_t width = 0;
88 uint32_t height = 0;
89 uint32_t levels = 0;
90 TexelFormat format = TexelFormat::Rgba8;
91 TexelColorSpace colorSpace = TexelColorSpace::Linear;
92 std::vector<uint32_t> words;
93 bool failed = false;
94 };
95
96 struct Entry {
97 Ref<device::Buffer> texels;
98 Ref<device::Texture> texture;
99 TexelFormat format = TexelFormat::Rgba8;
100 TexelColorSpace colorSpace = TexelColorSpace::Linear;
101 uint32_t width = 0;
102 uint32_t height = 0;
103 uint32_t levels = 0;
104 std::array<uint32_t, kTextureMaxLevels> offsets{};
105 uint32_t users = 0;
106 bool ready = false;
107 bool failed = false;
108 };
109
110 507 struct Mips {
111 std::vector<std::vector<MipJob>> levels;
112 std::vector<std::pair<Ref<device::Buffer>, const Entry*>> copies;
113 };
114
115 void Acquire(const TextureKey& key);
116 void Upload(const TextureKey& key, Entry& entry, Decoded decoded, Mips& mips);
117 void Downsample(const Mips& mips);
118 device::Program& Kernels();
119 uint32_t AllocateDesc();
120 uint64_t DescAddress(uint32_t desc) const;
121
122 device::Device& m_device;
123 FileLookup m_files;
124 std::map<TextureKey, Entry> m_images;
125 std::vector<Ref<device::Buffer>> m_descChunks;
126 std::vector<uint32_t> m_freeDescs;
127 uint32_t m_descCount = 0;
128 std::vector<uint64_t> m_bindings = {0};
129 std::map<uint32_t, std::vector<uint32_t>> m_freeBindings;
130 Ref<device::Buffer> m_bindingBuffer;
131 bool m_bindingsChanged = true;
132 uint32_t m_loaded = 0;
133 uint32_t m_failed = 0;
134 mutable std::mutex m_mutex;
135 std::condition_variable m_settled;
136 std::vector<std::pair<TextureKey, Decoded>> m_done;
137 uint32_t m_inFlight = 0;
138 Ref<device::Program> m_program;
139 ThreadPool m_pool;
140 };
141
142 }
143