diff --git a/interfaces/Crafter.Graphics-FontAtlas.cppm b/interfaces/Crafter.Graphics-FontAtlas.cppm index 4f72522..732455d 100644 --- a/interfaces/Crafter.Graphics-FontAtlas.cppm +++ b/interfaces/Crafter.Graphics-FontAtlas.cppm @@ -96,6 +96,18 @@ export namespace Crafter { bool dirty = false; DirtyRect dirtyRect; +#ifndef CRAFTER_GRAPHICS_WINDOW_DOM + FontAtlas() = default; + FontAtlas(const FontAtlas&) = delete; + FontAtlas& operator=(const FontAtlas&) = delete; + // The image goes with the atlas. The owner waits for the GPU first + // and, in sets mode, destroys the heap holding the image's view before + // the atlas. + ~FontAtlas() { + if (image.image != VK_NULL_HANDLE) image.Destroy(); + } +#endif + void Initialize(GraphicsCommandBuffer cmd); // Returns the row-major byte pointer the CPU writes pixels into. diff --git a/interfaces/Crafter.Graphics-ImageVulkan.cppm b/interfaces/Crafter.Graphics-ImageVulkan.cppm index 3864d60..8ae4df8 100644 --- a/interfaces/Crafter.Graphics-ImageVulkan.cppm +++ b/interfaces/Crafter.Graphics-ImageVulkan.cppm @@ -56,8 +56,8 @@ export namespace Crafter { std::uint16_t width; std::uint16_t height; std::uint8_t mipLevels; - VkImage image; - VkDeviceMemory imageMemory; + VkImage image = VK_NULL_HANDLE; + VkDeviceMemory imageMemory = VK_NULL_HANDLE; VulkanBuffer buffer; // Transient host-visible staging for the compressed Update path. Same // lifetime contract as Mesh::compressedStaging: the compressed Update @@ -66,7 +66,7 @@ export namespace Crafter { // submit's frame has cleared instead of pinning it for the image's life. // Between Updates the handle is null; the next Update's Resize re-creates it. VulkanBuffer compressedStaging; - VkImageView imageView; + VkImageView imageView = VK_NULL_HANDLE; VkDescriptorImageInfo descriptor; // Pipeline stage that samples this image after upload. Set once at // Create and reused by every Update so the upload barrier's dst (and @@ -378,6 +378,9 @@ export namespace Crafter { vkDestroyImageView(Device::device, imageView, nullptr); vkDestroyImage(Device::device, image, nullptr); vkFreeMemory(Device::device, imageMemory, nullptr); + imageView = VK_NULL_HANDLE; + image = VK_NULL_HANDLE; + imageMemory = VK_NULL_HANDLE; // Free any staging this image still owns: a streamed image's // persistent `buffer`, or either staging buffer on an image // destroyed before its first upload released them (issue #114).