From 4e1e26b69667f7afd565799f30f045b2e042cdcb Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Sun, 18 Feb 2024 21:18:59 -0800 Subject: [PATCH] blade: Fix initialization of atlas textures used for path rasterization (#8000) Generally the BladeAtlas logic has been deferring all the texture initializations and updates till `begin_frame`. This doesn't work for path rasterization, since a texture needs to be allocated after `begin_frame` and used immediately. Fixed validation error: > UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout(ERROR / SPEC): msgNum: 1303270965 - Validation Error: [ UNASSIGNED-CoreValidation-DrawState-InvalidImageLayout ] Object 0: handle = 0x60ce301b9010, name = main, type = VK_OBJECT_TYPE_COMMAND_BUFFER; Object 1: handle = 0x51820000000007b, name = atlas, type = VK_OBJECT_TYPE_IMAGE; | MessageID = 0x4dae5635 | vkQueueSubmit(): pSubmits[0].pCommandBuffers[0] command buffer VkCommandBuffer 0x60ce301b9010[main] expects VkImage 0x51820000000007b[atlas] (subresource: aspectMask 0x1 array layer 0, mip level 0) to be in layout VK_IMAGE_LAYOUT_GENERAL--instead, current layout is VK_IMAGE_LAYOUT_UNDEFINED. Objects: 2 [0] 0x60ce301b9010, type: 6, name: main [1] 0x51820000000007b, type: 10, name: atlas Release Notes: - N/A --- crates/gpui/src/platform/blade/blade_atlas.rs | 18 +++++++++++++++--- .../gpui/src/platform/blade/blade_renderer.rs | 8 +++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/crates/gpui/src/platform/blade/blade_atlas.rs b/crates/gpui/src/platform/blade/blade_atlas.rs index 461566648897c8d5e3bd508f657173edf264098d..ccebc93b308da264c0b3f45ac6cd1f45a3098bbf 100644 --- a/crates/gpui/src/platform/blade/blade_atlas.rs +++ b/crates/gpui/src/platform/blade/blade_atlas.rs @@ -69,9 +69,17 @@ impl BladeAtlas { } } - pub fn allocate(&self, size: Size, texture_kind: AtlasTextureKind) -> AtlasTile { + /// Allocate a rectangle and make it available for rendering immediately (without waiting for `before_frame`) + pub fn allocate_for_rendering( + &self, + size: Size, + texture_kind: AtlasTextureKind, + gpu_encoder: &mut gpu::CommandEncoder, + ) -> AtlasTile { let mut lock = self.0.lock(); - lock.allocate(size, texture_kind) + let tile = lock.allocate(size, texture_kind); + lock.flush_initializations(gpu_encoder); + tile } pub fn before_frame(&self, gpu_encoder: &mut gpu::CommandEncoder) { @@ -204,11 +212,15 @@ impl BladeAtlasState { self.uploads.push(PendingUpload { id, bounds, data }); } - fn flush(&mut self, encoder: &mut gpu::CommandEncoder) { + fn flush_initializations(&mut self, encoder: &mut gpu::CommandEncoder) { for id in self.initializations.drain(..) { let texture = &self.storage[id]; encoder.init_texture(texture.raw); } + } + + fn flush(&mut self, encoder: &mut gpu::CommandEncoder) { + self.flush_initializations(encoder); let mut transfers = encoder.transfer(); for upload in self.uploads.drain(..) { diff --git a/crates/gpui/src/platform/blade/blade_renderer.rs b/crates/gpui/src/platform/blade/blade_renderer.rs index ce835073b15ebf3a67e7c9375402ede92ee87c5d..d715bed895b9b5d2cdf449bd9ffe3e5f0d439b86 100644 --- a/crates/gpui/src/platform/blade/blade_renderer.rs +++ b/crates/gpui/src/platform/blade/blade_renderer.rs @@ -450,9 +450,11 @@ impl BladeRenderer { for path in paths { let clipped_bounds = path.bounds.intersect(&path.content_mask.bounds); - let tile = self - .atlas - .allocate(clipped_bounds.size.map(Into::into), AtlasTextureKind::Path); + let tile = self.atlas.allocate_for_rendering( + clipped_bounds.size.map(Into::into), + AtlasTextureKind::Path, + &mut self.command_encoder, + ); vertices_by_texture_id .entry(tile.texture_id) .or_insert(Vec::new())