move surface methods on the Surface

This commit is contained in:
teoxoy 2024-10-11 16:47:41 +02:00 committed by Teodor Tanasoaia
parent 26624c04e0
commit b7d465a2b4

View File

@ -17,7 +17,9 @@ use crate::{
conv, conv,
device::{Device, DeviceError, MissingDownlevelFlags, WaitIdleError}, device::{Device, DeviceError, MissingDownlevelFlags, WaitIdleError},
global::Global, global::Global,
hal_label, id, resource, hal_label, id,
instance::Surface,
resource,
}; };
use thiserror::Error; use thiserror::Error;
@ -106,6 +108,12 @@ impl From<WaitIdleError> for ConfigureSurfaceError {
} }
} }
#[derive(Debug)]
pub struct ResolvedSurfaceOutput {
pub status: Status,
pub texture: Option<Arc<resource::Texture>>,
}
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct SurfaceOutput { pub struct SurfaceOutput {
@ -113,39 +121,21 @@ pub struct SurfaceOutput {
pub texture_id: Option<id::TextureId>, pub texture_id: Option<id::TextureId>,
} }
impl Global { impl Surface {
pub fn surface_get_current_texture( pub fn get_current_texture(&self) -> Result<ResolvedSurfaceOutput, SurfaceError> {
&self, profiling::scope!("Surface::get_current_texture");
surface_id: id::SurfaceId,
texture_id_in: Option<id::TextureId>,
) -> Result<SurfaceOutput, SurfaceError> {
profiling::scope!("SwapChain::get_next_texture");
let hub = &self.hub; let (device, config) = if let Some(ref present) = *self.presentation.lock() {
let surface = self.surfaces.get(surface_id);
let (device, config) = if let Some(ref present) = *surface.presentation.lock() {
present.device.check_is_valid()?; present.device.check_is_valid()?;
(present.device.clone(), present.config.clone()) (present.device.clone(), present.config.clone())
} else { } else {
return Err(SurfaceError::NotConfigured); return Err(SurfaceError::NotConfigured);
}; };
let fid = hub.textures.prepare(texture_id_in);
#[cfg(feature = "trace")]
if let Some(ref mut trace) = *device.trace.lock() {
trace.add(Action::GetSurfaceTexture {
id: fid.id(),
parent_id: surface_id,
});
}
let fence = device.fence.read(); let fence = device.fence.read();
let suf = surface.raw(device.backend()).unwrap(); let suf = self.raw(device.backend()).unwrap();
let (texture_id, status) = match unsafe { let (texture, status) = match unsafe {
suf.acquire_texture( suf.acquire_texture(
Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)), Some(std::time::Duration::from_millis(FRAME_TIMEOUT_MS as u64)),
fence.as_ref(), fence.as_ref(),
@ -191,7 +181,7 @@ impl Global {
} }
.map_err(|e| device.handle_hal_error(e))?; .map_err(|e| device.handle_hal_error(e))?;
let mut presentation = surface.presentation.lock(); let mut presentation = self.presentation.lock();
let present = presentation.as_mut().unwrap(); let present = presentation.as_mut().unwrap();
let texture = resource::Texture::new( let texture = resource::Texture::new(
&device, &device,
@ -218,14 +208,12 @@ impl Global {
} }
present.acquired_texture = Some(texture.clone()); present.acquired_texture = Some(texture.clone());
let id = fid.assign(resource::Fallible::Valid(texture));
let status = if ast.suboptimal { let status = if ast.suboptimal {
Status::Suboptimal Status::Suboptimal
} else { } else {
Status::Good Status::Good
}; };
(Some(id), status) (Some(texture), status)
} }
Ok(None) => (None, Status::Timeout), Ok(None) => (None, Status::Timeout),
Err(err) => ( Err(err) => (
@ -244,15 +232,13 @@ impl Global {
), ),
}; };
Ok(SurfaceOutput { status, texture_id }) Ok(ResolvedSurfaceOutput { status, texture })
} }
pub fn surface_present(&self, surface_id: id::SurfaceId) -> Result<Status, SurfaceError> { pub fn present(&self) -> Result<Status, SurfaceError> {
profiling::scope!("SwapChain::present"); profiling::scope!("Surface::present");
let surface = self.surfaces.get(surface_id); let mut presentation = self.presentation.lock();
let mut presentation = surface.presentation.lock();
let present = match presentation.as_mut() { let present = match presentation.as_mut() {
Some(present) => present, Some(present) => present,
None => return Err(SurfaceError::NotConfigured), None => return Err(SurfaceError::NotConfigured),
@ -260,11 +246,6 @@ impl Global {
let device = &present.device; let device = &present.device;
#[cfg(feature = "trace")]
if let Some(ref mut trace) = *device.trace.lock() {
trace.add(Action::Present(surface_id));
}
device.check_is_valid()?; device.check_is_valid()?;
let queue = device.get_queue().unwrap(); let queue = device.get_queue().unwrap();
@ -276,7 +257,7 @@ impl Global {
let result = match texture.inner.snatch(&mut device.snatchable_lock.write()) { let result = match texture.inner.snatch(&mut device.snatchable_lock.write()) {
None => return Err(SurfaceError::TextureDestroyed), None => return Err(SurfaceError::TextureDestroyed),
Some(resource::TextureInner::Surface { raw }) => { Some(resource::TextureInner::Surface { raw }) => {
let raw_surface = surface.raw(device.backend()).unwrap(); let raw_surface = self.raw(device.backend()).unwrap();
let raw_queue = queue.raw(); let raw_queue = queue.raw();
unsafe { raw_queue.present(raw_surface, raw) } unsafe { raw_queue.present(raw_surface, raw) }
} }
@ -299,11 +280,10 @@ impl Global {
} }
} }
pub fn surface_texture_discard(&self, surface_id: id::SurfaceId) -> Result<(), SurfaceError> { pub fn discard(&self) -> Result<(), SurfaceError> {
profiling::scope!("SwapChain::discard"); profiling::scope!("Surface::discard");
let surface = self.surfaces.get(surface_id); let mut presentation = self.presentation.lock();
let mut presentation = surface.presentation.lock();
let present = match presentation.as_mut() { let present = match presentation.as_mut() {
Some(present) => present, Some(present) => present,
None => return Err(SurfaceError::NotConfigured), None => return Err(SurfaceError::NotConfigured),
@ -311,11 +291,6 @@ impl Global {
let device = &present.device; let device = &present.device;
#[cfg(feature = "trace")]
if let Some(ref mut trace) = *device.trace.lock() {
trace.add(Action::DiscardSurfaceTexture(surface_id));
}
device.check_is_valid()?; device.check_is_valid()?;
let texture = present let texture = present
@ -326,7 +301,7 @@ impl Global {
match texture.inner.snatch(&mut device.snatchable_lock.write()) { match texture.inner.snatch(&mut device.snatchable_lock.write()) {
None => return Err(SurfaceError::TextureDestroyed), None => return Err(SurfaceError::TextureDestroyed),
Some(resource::TextureInner::Surface { raw }) => { Some(resource::TextureInner::Surface { raw }) => {
let raw_surface = surface.raw(device.backend()).unwrap(); let raw_surface = self.raw(device.backend()).unwrap();
unsafe { raw_surface.discard_texture(raw) }; unsafe { raw_surface.discard_texture(raw) };
} }
_ => unreachable!(), _ => unreachable!(),
@ -335,3 +310,60 @@ impl Global {
Ok(()) Ok(())
} }
} }
impl Global {
pub fn surface_get_current_texture(
&self,
surface_id: id::SurfaceId,
texture_id_in: Option<id::TextureId>,
) -> Result<SurfaceOutput, SurfaceError> {
let surface = self.surfaces.get(surface_id);
let fid = self.hub.textures.prepare(texture_id_in);
#[cfg(feature = "trace")]
if let Some(present) = surface.presentation.lock().as_ref() {
if let Some(ref mut trace) = *present.device.trace.lock() {
trace.add(Action::GetSurfaceTexture {
id: fid.id(),
parent_id: surface_id,
});
}
}
let output = surface.get_current_texture()?;
let status = output.status;
let texture_id = output
.texture
.map(|texture| fid.assign(resource::Fallible::Valid(texture)));
Ok(SurfaceOutput { status, texture_id })
}
pub fn surface_present(&self, surface_id: id::SurfaceId) -> Result<Status, SurfaceError> {
let surface = self.surfaces.get(surface_id);
#[cfg(feature = "trace")]
if let Some(present) = surface.presentation.lock().as_ref() {
if let Some(ref mut trace) = *present.device.trace.lock() {
trace.add(Action::Present(surface_id));
}
}
surface.present()
}
pub fn surface_texture_discard(&self, surface_id: id::SurfaceId) -> Result<(), SurfaceError> {
let surface = self.surfaces.get(surface_id);
#[cfg(feature = "trace")]
if let Some(present) = surface.presentation.lock().as_ref() {
if let Some(ref mut trace) = *present.device.trace.lock() {
trace.add(Action::DiscardSurfaceTexture(surface_id));
}
}
surface.discard()
}
}