Remove text caching logic and m_lastRenderedText. Switch to direct
memory-mapped updates of dynamic vertex and index buffers each frame,
eliminating staging/caching paths and simplifying debug/update logic.
Move geometry and text to single host-visible vertex/index buffers
created once and updated via vkMapMemory (no staging). Add
createDynamic*/updateDynamicBuffer helpers. Reduce vkWaitForFences
timeout from 5s to 100ms and skip/log on timeout to avoid blocking.
Update geometry only periodically (every 5 frames) and reduce logging
frequency. Destroy and null out old buffers before recreating them to
avoid double frees and leaks.
Cache lastRenderedText and only rebuild text vertex/index buffers when
the content or size changes; reuse buffers across frames and clean them
up on rebuild or shutdown.
Replace vkDeviceWaitIdle in copyBuffer with fence-based wait (longer
timeout) and remove noisy debug prints. Added members and cleanup for
text buffers and index count
Increase MAX_FRAMES_IN_FLIGHT to 3 and cap swapchain images accordingly
Replace vkDeviceWaitIdle with per-copy fence, extend wait timeout and
add diagnostic logging and counters Add stronger error logging and
cleanup on vertex/index buffer creation and copy failures; reset handles
to VK_NULL_HANDLE on failure
Create a VkFence for the copy command, submit with that fence, wait with
vkWaitForFences instead of vkQueueWaitIdle, and destroy the fence after
completion. Ensure fence is destroyed and the command buffer is freed on
error paths.