diff options
author | quou <quou@disroot.org> | 2025-01-01 10:37:39 +1100 |
---|---|---|
committer | quou <quou@disroot.org> | 2025-01-01 10:44:04 +1100 |
commit | aabe67b66267cea431f5936a2b3a9c38ed94eaff (patch) | |
tree | 1117142f6caea51064f66d30ce6417eab84f8c6b | |
parent | 076c83525ff33a756bf1aac63fe202f5e02c86b0 (diff) |
device debug interface
-rw-r--r-- | video.cpp | 171 | ||||
-rw-r--r-- | video.hpp | 20 |
2 files changed, 154 insertions, 37 deletions
@@ -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; +} @@ -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(); |