summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorquou <quou@disroot.org>2025-01-01 10:37:39 +1100
committerquou <quou@disroot.org>2025-01-01 10:44:04 +1100
commitaabe67b66267cea431f5936a2b3a9c38ed94eaff (patch)
tree1117142f6caea51064f66d30ce6417eab84f8c6b
parent076c83525ff33a756bf1aac63fe202f5e02c86b0 (diff)
device debug interface
-rw-r--r--video.cpp171
-rw-r--r--video.hpp20
2 files changed, 154 insertions, 37 deletions
diff --git a/video.cpp b/video.cpp
index 3148500..1f58e00 100644
--- a/video.cpp
+++ b/video.cpp
@@ -114,6 +114,12 @@ struct Hash_Map {
return values[bucket];
}
+ Key* kaddr(const Key& k) {
+ int bucket = find(k);
+ if (bucket < 0 || flags[bucket] & flags_null) return 0;
+ return &keys[bucket];
+ }
+
void remove(const Key& k) {
int bucket = find(k);
assert(bucket >= 0);
@@ -1044,7 +1050,9 @@ struct Device_Vk : public Device {
const Pipeline_Vk& pip,
const Dso_Key& k
);
-
+
+ template<typename List, typename F>
+ void collect_objects(List& list, int max_age, F f);
void collect_garbage();
void queue_destroy(Late_Terminated* obj);
void create_terminators();
@@ -1472,7 +1480,12 @@ Renderpass_Vk& Device_Vk::create_rpo(const Rpo_Key& k) {
Renderpass_Vk rpo;
rpo.init(this, k);
rpo.age = 0;
- return rpo_cache.set(k, rpo);
+ auto& r = rpo_cache.set(k, rpo);
+#ifdef DEBUG
+ if (hooks)
+ hooks->on_rpo_create(rpo_cache.kaddr(k)->rpo);
+#endif
+ return r;
}
Renderpass_Vk& Device_Vk::get_rpo(const Rpo_Key& rp) {
@@ -1490,7 +1503,12 @@ Framebuffer_Vk& Device_Vk::create_fbo(
Framebuffer_Vk fbo;
fbo.init(this, rpo, fb);
fbo.age = 0;
- return fbo_cache.set(k, fbo);
+ auto& r = fbo_cache.set(k, fbo);
+#ifdef DEBUG
+ if (hooks)
+ hooks->on_fbo_create(fbo_cache.kaddr(k)->rpo);
+#endif
+ return r;
}
Framebuffer_Vk& Device_Vk::get_fbo(
@@ -1507,7 +1525,12 @@ Pipeline_Vk& Device_Vk::create_pso(const Pso_Key& pip) {
Pipeline_Vk pso;
pso.age = 0;
pso.init(this, pip);
- return pso_cache.set(pip, pso);
+ auto& r = pso_cache.set(pip, pso);
+#ifdef DEBUG
+ if (hooks)
+ hooks->on_pso_create(pso_cache.kaddr(pip)->pso);
+#endif
+ return r;
}
Pipeline_Vk& Device_Vk::get_pso(const Pso_Key& pip) {
@@ -1524,7 +1547,12 @@ Descriptor_Set_Vk& Device_Vk::create_dso(
Descriptor_Set_Vk dso;
dso.age = 0;
dso.init(this, pip, k.pip);
- return dso_cache.set(k, dso);
+ auto& r = dso_cache.set(k, dso);
+#ifdef DEBUG
+ if (hooks)
+ hooks->on_dso_create(dso_cache.kaddr(k)->pip);
+#endif
+ return r;
}
Descriptor_Set_Vk& Device_Vk::get_dso(
@@ -1537,42 +1565,47 @@ Descriptor_Set_Vk& Device_Vk::get_dso(
return *dso;
}
-void Device_Vk::collect_garbage() {
- int max_age = swapchain.image_count + 3;
- for (const auto& i: rpo_cache) {
- auto& rp = i.second;
- rp.age++;
- if (rp.age > max_age) {
- rp.destroy(this);
- rpo_cache.remove(i.first);
- }
- }
- for (const auto& i: fbo_cache) {
- auto& fb = i.second;
- fb.age++;
- if (fb.age > max_age) {
- fb.destroy(this);
- fbo_cache.remove(i.first);
- }
- }
- for (const auto& i: pso_cache) {
- auto& pip = i.second;
- pip.age++;
- if (pip.age > max_age) {
- pip.destroy(this);
- pso_cache.remove(i.first);
- }
- }
- for (const auto& i: dso_cache) {
- auto& dso = i.second;
- dso.age++;
- if (dso.age > max_age) {
- dso.destroy(this);
- dso_cache.remove(i.first);
+template<typename List, typename F>
+void Device_Vk::collect_objects(List& list, int max_age, F f) {
+ for (auto i : list) {
+ auto& obj = i.second;
+ obj.age++;
+ if (obj.age > max_age) {
+ f(i);
+ obj.destroy(this);
+ list.remove(i.first);
}
}
}
+void Device_Vk::collect_garbage() {
+ int max_age = swapchain.image_count + 3;
+ collect_objects(rpo_cache, max_age, [this](auto i){
+#ifdef DEBUG
+ if (hooks)
+ hooks->on_rpo_destroy(rpo_cache.kaddr(i.first)->rpo);
+#endif
+ });
+ collect_objects(fbo_cache, max_age, [this](auto i){
+#ifdef DEBUG
+ if (hooks)
+ hooks->on_fbo_destroy(fbo_cache.kaddr(i.first)->rpo);
+#endif
+ });
+ collect_objects(pso_cache, max_age, [this](auto i){
+#ifdef DEBUG
+ if (hooks)
+ hooks->on_pso_destroy(pso_cache.kaddr(i.first)->pso);
+#endif
+ });
+ collect_objects(dso_cache, max_age, [this](auto i){
+#ifdef DEBUG
+ if (hooks)
+ hooks->on_dso_destroy(dso_cache.kaddr(i.first)->pip);
+#endif
+ });
+}
+
void Device_Vk::queue_destroy(Late_Terminated* obj) {
terminators[terminator_index].add(obj);
}
@@ -1910,6 +1943,7 @@ void Device::init(Arena* a, App* ap) {
hm = arena_alloc(a, device_heap_size);
heap = (Heap*)arena_alloc(a, sizeof *heap);
init_heap(heap, hm, device_heap_size);
+ hooks = 0;
((Device_Vk*)this)->init_internal();
}
@@ -1917,6 +1951,11 @@ void Device::destroy() {
((Device_Vk*)this)->deinit_internal();
}
+void Device::register_hooks(Device_Debug_Hooks* h) {
+ h->dev = this;
+ hooks = h;
+}
+
void Device::on_resize() {
((Device_Vk*)this)->on_resize_internal(app->w, app->h);
}
@@ -1956,6 +1995,10 @@ void Device::submit(Context& ctx_) {
vkEndCommandBuffer(ctx->cb);
vkQueueSubmit(dev->queue, 1, &si, ctx->fence);
ctx->wait();
+#ifdef DEBUG
+ if (dev->hooks)
+ dev->hooks->on_submit(*ctx);
+#endif
ctx->release();
}
@@ -1988,6 +2031,12 @@ void Device::present() {
pi.pSwapchains = &dev->swapchain.swapchain;
pi.pImageIndices = &dev->backbuffer_index;
vkQueuePresentKHR(dev->queue, &pi);
+#ifdef DEBUG
+ if (hooks) {
+ hooks->on_submit(*ctx);
+ hooks->on_present(*ctx);
+ }
+#endif
ctx->release();
}
@@ -2483,6 +2532,10 @@ Context_Vk& Context_Vk::acquire(Device_Vk* device) {
init(device);
state &= ~context_state_avail;
begin_record();
+#ifdef DEBUG
+ if (device->hooks)
+ device->hooks->on_acquire(*this);
+#endif
return *this;
}
@@ -3946,3 +3999,47 @@ void Staged_Buffer::unmap(Device* dev) {
void Staged_Buffer::update(Context& ctx) {
ctx.copy(gpuonly, stage);
}
+
+void Device_Debug_Hooks::on_rpo_create(const Render_Pass& rpo) {
+ (void)rpo;
+}
+
+void Device_Debug_Hooks::on_rpo_destroy(const Render_Pass& rpo) {
+ (void)rpo;
+}
+
+void Device_Debug_Hooks::on_fbo_create(const Render_Pass& pass) {
+ (void)pass;
+}
+
+void Device_Debug_Hooks::on_fbo_destroy(const Render_Pass& pass) {
+ (void)pass;
+}
+
+void Device_Debug_Hooks::on_pso_create(const Pipeline& pso) {
+ (void)pso;
+}
+
+void Device_Debug_Hooks::on_pso_destroy(const Pipeline& pso) {
+ (void)pso;
+}
+
+void Device_Debug_Hooks::on_dso_create(const Pipeline& pso) {
+ (void)pso;
+}
+
+void Device_Debug_Hooks::on_dso_destroy(const Pipeline& pso) {
+ (void)pso;
+}
+
+void Device_Debug_Hooks::on_acquire(Context& ctx) {
+ (void)ctx;
+}
+
+void Device_Debug_Hooks::on_submit(Context& ctx) {
+ (void)ctx;
+}
+
+void Device_Debug_Hooks::on_present(Context& ctx) {
+ (void)ctx;
+}
diff --git a/video.hpp b/video.hpp
index 2148d8f..bc57f1f 100644
--- a/video.hpp
+++ b/video.hpp
@@ -408,17 +408,37 @@ struct Vertex_Format_Desc {
int attribute_count;
};
+struct Device;
+struct Context;
+struct Device_Debug_Hooks {
+ Device* dev;
+ virtual void on_rpo_create(const Render_Pass& rpo);
+ virtual void on_rpo_destroy(const Render_Pass& rpo);
+ virtual void on_fbo_create(const Render_Pass& pass);
+ virtual void on_fbo_destroy(const Render_Pass& pass);
+ virtual void on_pso_create(const Pipeline& pso);
+ virtual void on_pso_destroy(const Pipeline& pso);
+ virtual void on_dso_create(const Pipeline& pso);
+ virtual void on_dso_destroy(const Pipeline& pso);
+ virtual void on_acquire(Context& ctx);
+ virtual void on_submit(Context& ctx);
+ virtual void on_present(Context& ctx);
+};
+
struct Context;
struct Shader;
struct Device {
Arena* arena;
Heap* heap;
App* app;
+ Device_Debug_Hooks* hooks;
static Device* create(Arena* a, App* ap);
void init(Arena* a, App* ap);
void destroy();
+ void register_hooks(Device_Debug_Hooks* hooks);
+
void on_resize();
void begin_frame();