1
0
Fork 0
forked from wry/wry

Merge pull request #376 from mahkoh/jorth/vulkan-fixes

Various vulkan fixes
This commit is contained in:
mahkoh 2025-02-21 11:56:24 +01:00 committed by GitHub
commit b00f3a2ffe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 71 additions and 58 deletions

View file

@ -257,23 +257,8 @@ pub enum ResetStatus {
pub trait GfxFramebuffer: Debug { pub trait GfxFramebuffer: Debug {
fn physical_size(&self) -> (i32, i32); fn physical_size(&self) -> (i32, i32);
fn full_region(&self) -> Region {
let (width, height) = self.physical_size();
Region::new2(Rect::new_sized_unchecked(0, 0, width, height))
}
fn render(
&self,
acquire_sync: AcquireSync,
release_sync: ReleaseSync,
ops: &[GfxApiOpt],
clear: Option<&Color>,
) -> Result<Option<SyncFile>, GfxError> {
self.render_with_region(acquire_sync, release_sync, ops, clear, &self.full_region())
}
fn render_with_region( fn render_with_region(
&self, self: Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
release_sync: ReleaseSync, release_sync: ReleaseSync,
ops: &[GfxApiOpt], ops: &[GfxApiOpt],
@ -300,8 +285,24 @@ pub trait GfxInternalFramebuffer: GfxFramebuffer {
} }
impl dyn GfxFramebuffer { impl dyn GfxFramebuffer {
pub fn render(
self: &Rc<Self>,
acquire_sync: AcquireSync,
release_sync: ReleaseSync,
ops: &[GfxApiOpt],
clear: Option<&Color>,
) -> Result<Option<SyncFile>, GfxError> {
self.clone()
.render_with_region(acquire_sync, release_sync, ops, clear, &self.full_region())
}
fn full_region(&self) -> Region {
let (width, height) = self.physical_size();
Region::new2(Rect::new_sized_unchecked(0, 0, width, height))
}
pub fn clear( pub fn clear(
&self, self: &Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
release_sync: ReleaseSync, release_sync: ReleaseSync,
) -> Result<Option<SyncFile>, GfxError> { ) -> Result<Option<SyncFile>, GfxError> {
@ -309,7 +310,7 @@ impl dyn GfxFramebuffer {
} }
pub fn clear_with( pub fn clear_with(
&self, self: &Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
release_sync: ReleaseSync, release_sync: ReleaseSync,
r: f32, r: f32,
@ -334,7 +335,7 @@ impl dyn GfxFramebuffer {
} }
pub fn copy_texture( pub fn copy_texture(
&self, self: &Rc<Self>,
fb_acquire_sync: AcquireSync, fb_acquire_sync: AcquireSync,
fb_release_sync: ReleaseSync, fb_release_sync: ReleaseSync,
texture: &Rc<dyn GfxTexture>, texture: &Rc<dyn GfxTexture>,
@ -365,7 +366,7 @@ impl dyn GfxFramebuffer {
} }
pub fn render_custom( pub fn render_custom(
&self, self: &Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
release_sync: ReleaseSync, release_sync: ReleaseSync,
scale: Scale, scale: Scale,
@ -407,13 +408,13 @@ impl dyn GfxFramebuffer {
} }
pub fn perform_render_pass( pub fn perform_render_pass(
&self, self: &Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
release_sync: ReleaseSync, release_sync: ReleaseSync,
pass: &GfxRenderPass, pass: &GfxRenderPass,
region: &Region, region: &Region,
) -> Result<Option<SyncFile>, GfxError> { ) -> Result<Option<SyncFile>, GfxError> {
self.render_with_region( self.clone().render_with_region(
acquire_sync, acquire_sync,
release_sync, release_sync,
&pass.ops, &pass.ops,
@ -423,7 +424,7 @@ impl dyn GfxFramebuffer {
} }
pub fn render_output( pub fn render_output(
&self, self: &Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
release_sync: ReleaseSync, release_sync: ReleaseSync,
node: &OutputNode, node: &OutputNode,
@ -449,7 +450,7 @@ impl dyn GfxFramebuffer {
} }
pub fn render_node( pub fn render_node(
&self, self: &Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
release_sync: ReleaseSync, release_sync: ReleaseSync,
node: &dyn Node, node: &dyn Node,
@ -478,7 +479,7 @@ impl dyn GfxFramebuffer {
} }
pub fn render_hardware_cursor( pub fn render_hardware_cursor(
&self, self: &Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
release_sync: ReleaseSync, release_sync: ReleaseSync,
cursor: &dyn Cursor, cursor: &dyn Cursor,

View file

@ -100,14 +100,16 @@ impl GfxFramebuffer for Framebuffer {
} }
fn render_with_region( fn render_with_region(
&self, self: Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
_release_sync: ReleaseSync, _release_sync: ReleaseSync,
ops: &[GfxApiOpt], ops: &[GfxApiOpt],
clear: Option<&Color>, clear: Option<&Color>,
_region: &Region, _region: &Region,
) -> Result<Option<SyncFile>, GfxError> { ) -> Result<Option<SyncFile>, GfxError> {
self.render(acquire_sync, ops, clear).map_err(|e| e.into()) (*self)
.render(acquire_sync, ops, clear)
.map_err(|e| e.into())
} }
fn format(&self) -> &'static Format { fn format(&self) -> &'static Format {

View file

@ -66,6 +66,7 @@ pub struct VulkanImage {
pub(super) shader_read_only_optimal_descriptor: Box<[u8]>, pub(super) shader_read_only_optimal_descriptor: Box<[u8]>,
pub(super) descriptor_buffer_version: Cell<u64>, pub(super) descriptor_buffer_version: Cell<u64>,
pub(super) descriptor_buffer_offset: Cell<DeviceSize>, pub(super) descriptor_buffer_offset: Cell<DeviceSize>,
pub(super) execution_version: Cell<u64>,
} }
#[derive(Copy, Clone, Eq, PartialEq, Debug)] #[derive(Copy, Clone, Eq, PartialEq, Debug)]
@ -452,6 +453,7 @@ impl VulkanDmaBufImageTemplate {
.sampler_read_only_descriptor(texture_view), .sampler_read_only_descriptor(texture_view),
descriptor_buffer_version: Cell::new(0), descriptor_buffer_version: Cell::new(0),
descriptor_buffer_offset: Cell::new(0), descriptor_buffer_offset: Cell::new(0),
execution_version: Cell::new(0),
})) }))
} }
@ -531,7 +533,7 @@ impl GfxFramebuffer for VulkanImage {
} }
fn render_with_region( fn render_with_region(
&self, self: Rc<Self>,
acquire_sync: AcquireSync, acquire_sync: AcquireSync,
release_sync: ReleaseSync, release_sync: ReleaseSync,
ops: &[GfxApiOpt], ops: &[GfxApiOpt],
@ -539,7 +541,7 @@ impl GfxFramebuffer for VulkanImage {
region: &Region, region: &Region,
) -> Result<Option<SyncFile>, GfxError> { ) -> Result<Option<SyncFile>, GfxError> {
self.renderer self.renderer
.execute(self, acquire_sync, release_sync, ops, clear, region) .execute(&self, acquire_sync, release_sync, ops, clear, region)
.map_err(|e| e.into()) .map_err(|e| e.into())
} }

View file

@ -50,7 +50,7 @@ use {
SubmitInfo2, Viewport, WriteDescriptorSet, SubmitInfo2, Viewport, WriteDescriptorSet,
}, },
}, },
isnt::std_1::collections::IsntHashMapExt, isnt::std_1::{collections::IsntHashMapExt, primitive::IsntSliceExt},
linearize::{Linearize, StaticMap, static_map}, linearize::{Linearize, StaticMap, static_map},
std::{ std::{
cell::{Cell, RefCell}, cell::{Cell, RefCell},
@ -87,7 +87,6 @@ pub struct VulkanRenderer {
pub(super) shm_allocator: Rc<VulkanThreadedAllocator>, pub(super) shm_allocator: Rc<VulkanThreadedAllocator>,
pub(super) sampler: Rc<VulkanSampler>, pub(super) sampler: Rc<VulkanSampler>,
pub(super) tex_sampler_descriptor_buffer_cache: Rc<VulkanDescriptorBufferCache>, pub(super) tex_sampler_descriptor_buffer_cache: Rc<VulkanDescriptorBufferCache>,
pub(super) descriptor_buffer_version: NumCell<u64>,
pub(super) tex_descriptor_buffer_writer: RefCell<VulkanDescriptorBufferWriter>, pub(super) tex_descriptor_buffer_writer: RefCell<VulkanDescriptorBufferWriter>,
} }
@ -158,6 +157,7 @@ pub(super) struct PendingFrame {
point: u64, point: u64,
renderer: Rc<VulkanRenderer>, renderer: Rc<VulkanRenderer>,
cmd: Cell<Option<Rc<VulkanCommandBuffer>>>, cmd: Cell<Option<Rc<VulkanCommandBuffer>>>,
_fb: Rc<VulkanImage>,
_textures: Vec<UsedTexture>, _textures: Vec<UsedTexture>,
wait_semaphores: Cell<Vec<Rc<VulkanSemaphore>>>, wait_semaphores: Cell<Vec<Rc<VulkanSemaphore>>>,
waiter: Cell<Option<SpawnedFuture<()>>>, waiter: Cell<Option<SpawnedFuture<()>>>,
@ -253,7 +253,6 @@ impl VulkanDevice {
shm_allocator, shm_allocator,
sampler, sampler,
tex_sampler_descriptor_buffer_cache: tex_descriptor_buffer_cache, tex_sampler_descriptor_buffer_cache: tex_descriptor_buffer_cache,
descriptor_buffer_version: Default::default(),
tex_descriptor_buffer_writer, tex_descriptor_buffer_writer,
}); });
render.get_or_create_pipelines(XRGB8888.vk_format)?; render.get_or_create_pipelines(XRGB8888.vk_format)?;
@ -326,7 +325,7 @@ impl VulkanRenderer {
return Ok(()); return Ok(());
}; };
zone!("create_descriptor_buffer"); zone!("create_descriptor_buffer");
let version = self.descriptor_buffer_version.add_fetch(1); let version = self.allocate_point();
let memory = &mut *self.memory.borrow_mut(); let memory = &mut *self.memory.borrow_mut();
let writer = &mut *self.tex_descriptor_buffer_writer.borrow_mut(); let writer = &mut *self.tex_descriptor_buffer_writer.borrow_mut();
writer.clear(); writer.clear();
@ -367,12 +366,16 @@ impl VulkanRenderer {
let mut memory = self.memory.borrow_mut(); let mut memory = self.memory.borrow_mut();
memory.dmabuf_sample.clear(); memory.dmabuf_sample.clear();
memory.queue_transfer.clear(); memory.queue_transfer.clear();
let execution = self.allocate_point();
for cmd in opts { for cmd in opts {
if let GfxApiOpt::CopyTexture(c) = cmd { if let GfxApiOpt::CopyTexture(c) = cmd {
let tex = c.tex.clone().into_vk(&self.device.device); let tex = c.tex.clone().into_vk(&self.device.device);
if tex.contents_are_undefined.get() { if tex.contents_are_undefined.get() {
continue; continue;
} }
if tex.execution_version.replace(execution) == execution {
continue;
}
match tex.queue_state.get().acquire(QueueFamily::Gfx) { match tex.queue_state.get().acquire(QueueFamily::Gfx) {
QueueTransfer::Unnecessary => {} QueueTransfer::Unnecessary => {}
QueueTransfer::Possible => memory.queue_transfer.push(tex.clone()), QueueTransfer::Possible => memory.queue_transfer.push(tex.clone()),
@ -519,7 +522,7 @@ impl VulkanRenderer {
let rendering_attachment_info = { let rendering_attachment_info = {
let mut rai = RenderingAttachmentInfo::default() let mut rai = RenderingAttachmentInfo::default()
.image_view(fb.render_view.unwrap_or(fb.texture_view)) .image_view(fb.render_view.unwrap_or(fb.texture_view))
.image_layout(ImageLayout::GENERAL) .image_layout(ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
.load_op(AttachmentLoadOp::LOAD) .load_op(AttachmentLoadOp::LOAD)
.store_op(AttachmentStoreOp::STORE); .store_op(AttachmentStoreOp::STORE);
if let Some(clear) = load_clear { if let Some(clear) = load_clear {
@ -540,25 +543,27 @@ impl VulkanRenderer {
unsafe { unsafe {
self.device.device.cmd_begin_rendering(buf, &rendering_info); self.device.device.cmd_begin_rendering(buf, &rendering_info);
} }
if let Some(clear) = manual_clear { if memory.paint_regions.is_not_empty() {
let clear_attachment = ClearAttachment::default() if let Some(clear) = manual_clear {
.color_attachment(0) let clear_attachment = ClearAttachment::default()
.clear_value(clear) .color_attachment(0)
.aspect_mask(ImageAspectFlags::COLOR); .clear_value(clear)
memory.clear_rects.clear(); .aspect_mask(ImageAspectFlags::COLOR);
for region in &memory.paint_regions { memory.clear_rects.clear();
memory.clear_rects.push(ClearRect { for region in &memory.paint_regions {
rect: region.rect, memory.clear_rects.push(ClearRect {
base_array_layer: 0, rect: region.rect,
layer_count: 1, base_array_layer: 0,
}); layer_count: 1,
} });
unsafe { }
self.device.device.cmd_clear_attachments( unsafe {
buf, self.device.device.cmd_clear_attachments(
&[clear_attachment], buf,
&memory.clear_rects, &[clear_attachment],
); &memory.clear_rects,
);
}
} }
} }
} }
@ -1008,7 +1013,7 @@ impl VulkanRenderer {
} }
} }
fn create_pending_frame(self: &Rc<Self>, buf: Rc<VulkanCommandBuffer>) { fn create_pending_frame(self: &Rc<Self>, buf: Rc<VulkanCommandBuffer>, fb: &Rc<VulkanImage>) {
zone!("create_pending_frame"); zone!("create_pending_frame");
let point = self.allocate_point(); let point = self.allocate_point();
let mut memory = self.memory.borrow_mut(); let mut memory = self.memory.borrow_mut();
@ -1016,6 +1021,7 @@ impl VulkanRenderer {
point, point,
renderer: self.clone(), renderer: self.clone(),
cmd: Cell::new(Some(buf)), cmd: Cell::new(Some(buf)),
_fb: fb.clone(),
_textures: mem::take(&mut memory.textures), _textures: mem::take(&mut memory.textures),
wait_semaphores: Cell::new(mem::take(&mut memory.wait_semaphores)), wait_semaphores: Cell::new(mem::take(&mut memory.wait_semaphores)),
waiter: Cell::new(None), waiter: Cell::new(None),
@ -1037,7 +1043,7 @@ impl VulkanRenderer {
pub fn execute( pub fn execute(
self: &Rc<Self>, self: &Rc<Self>,
fb: &VulkanImage, fb: &Rc<VulkanImage>,
fb_acquire_sync: AcquireSync, fb_acquire_sync: AcquireSync,
fb_release_sync: ReleaseSync, fb_release_sync: ReleaseSync,
opts: &[GfxApiOpt], opts: &[GfxApiOpt],
@ -1053,6 +1059,7 @@ impl VulkanRenderer {
memory.queue_transfer.clear(); memory.queue_transfer.clear();
memory.wait_semaphores.clear(); memory.wait_semaphores.clear();
memory.release_fence.take(); memory.release_fence.take();
memory.descriptor_buffer.take();
memory.release_sync_file.take() memory.release_sync_file.take()
}; };
res.map(|_| sync_file) res.map(|_| sync_file)
@ -1102,7 +1109,7 @@ impl VulkanRenderer {
fn try_execute( fn try_execute(
self: &Rc<Self>, self: &Rc<Self>,
fb: &VulkanImage, fb: &Rc<VulkanImage>,
fb_acquire_sync: AcquireSync, fb_acquire_sync: AcquireSync,
fb_release_sync: ReleaseSync, fb_release_sync: ReleaseSync,
opts: &[GfxApiOpt], opts: &[GfxApiOpt],
@ -1127,7 +1134,7 @@ impl VulkanRenderer {
self.submit(buf.buffer)?; self.submit(buf.buffer)?;
self.import_release_semaphore(fb, fb_release_sync); self.import_release_semaphore(fb, fb_release_sync);
self.store_layouts(fb); self.store_layouts(fb);
self.create_pending_frame(buf); self.create_pending_frame(buf, fb);
Ok(()) Ok(())
} }

View file

@ -462,6 +462,7 @@ impl VulkanRenderer {
shader_read_only_optimal_descriptor: self.sampler_read_only_descriptor(view), shader_read_only_optimal_descriptor: self.sampler_read_only_descriptor(view),
descriptor_buffer_version: Cell::new(0), descriptor_buffer_version: Cell::new(0),
descriptor_buffer_offset: Cell::new(0), descriptor_buffer_offset: Cell::new(0),
execution_version: Cell::new(0),
}); });
let shm = match &img.ty { let shm = match &img.ty {
VulkanImageMemory::DmaBuf(_) => unreachable!(), VulkanImageMemory::DmaBuf(_) => unreachable!(),

View file

@ -377,7 +377,7 @@ impl GfxFramebuffer for TestGfxFb {
} }
fn render_with_region( fn render_with_region(
&self, self: Rc<Self>,
_acquire_sync: AcquireSync, _acquire_sync: AcquireSync,
_release_sync: ReleaseSync, _release_sync: ReleaseSync,
ops: &[GfxApiOpt], ops: &[GfxApiOpt],