aboutsummaryrefslogtreecommitdiff
path: root/stockton-render/src/draw/target.rs
diff options
context:
space:
mode:
Diffstat (limited to 'stockton-render/src/draw/target.rs')
-rw-r--r--stockton-render/src/draw/target.rs139
1 files changed, 56 insertions, 83 deletions
diff --git a/stockton-render/src/draw/target.rs b/stockton-render/src/draw/target.rs
index 8d308d9..23c15cc 100644
--- a/stockton-render/src/draw/target.rs
+++ b/stockton-render/src/draw/target.rs
@@ -11,7 +11,7 @@ use arrayvec::ArrayVec;
use hal::{
buffer::SubRange,
command::RenderAttachmentInfo,
- format::{ChannelType, Format},
+ format::{ChannelType, Format, ImageFeature},
image::{Extent, FramebufferAttachment, Usage as ImgUsage, ViewCapabilities},
pso::Viewport,
window::{CompositeAlphaMode, Extent2D, PresentMode, SwapchainConfig},
@@ -25,7 +25,8 @@ use super::{
pipeline::CompletePipeline,
ui::{UiPipeline, UiPoint},
};
-use crate::types::*;
+use crate::{error::EnvironmentError, types::*};
+use anyhow::{Context, Result};
#[derive(Debug, Clone)]
pub struct SwapchainProperties {
@@ -37,29 +38,23 @@ pub struct SwapchainProperties {
pub extent: Extent,
}
-/// Indicates the given property has no acceptable values
-pub enum NoSupportedValuesError {
- DepthFormat,
- PresentMode,
- CompositeAlphaMode,
-}
-
impl SwapchainProperties {
pub fn find_best(
adapter: &Adapter,
surface: &SurfaceT,
- ) -> Result<SwapchainProperties, NoSupportedValuesError> {
+ ) -> Result<SwapchainProperties, EnvironmentError> {
let caps = surface.capabilities(&adapter.physical_device);
let formats = surface.supported_formats(&adapter.physical_device);
// Find which settings we'll actually use based on preset preferences
- let format = formats.map_or(Format::Rgba8Srgb, |formats| {
- formats
+ let format = match formats {
+ Some(formats) => formats
.iter()
.find(|format| format.base_format().1 == ChannelType::Srgb)
.copied()
- .unwrap_or(formats[0])
- });
+ .ok_or(EnvironmentError::ColorFormat),
+ None => Ok(Format::Rgba8Srgb),
+ }?;
let depth_format = *[
Format::D32SfloatS8Uint,
@@ -68,8 +63,6 @@ impl SwapchainProperties {
]
.iter()
.find(|format| {
- use hal::format::ImageFeature;
-
format.is_depth()
&& adapter
.physical_device
@@ -77,32 +70,29 @@ impl SwapchainProperties {
.optimal_tiling
.contains(ImageFeature::DEPTH_STENCIL_ATTACHMENT)
})
- .ok_or(NoSupportedValuesError::DepthFormat)?;
-
- let present_mode = {
- [
- PresentMode::MAILBOX,
- PresentMode::FIFO,
- PresentMode::RELAXED,
- PresentMode::IMMEDIATE,
- ]
- .iter()
- .cloned()
- .find(|pm| caps.present_modes.contains(*pm))
- .ok_or(NoSupportedValuesError::PresentMode)?
- };
- let composite_alpha_mode = {
- [
- CompositeAlphaMode::OPAQUE,
- CompositeAlphaMode::INHERIT,
- CompositeAlphaMode::PREMULTIPLIED,
- CompositeAlphaMode::POSTMULTIPLIED,
- ]
- .iter()
- .cloned()
- .find(|ca| caps.composite_alpha_modes.contains(*ca))
- .ok_or(NoSupportedValuesError::CompositeAlphaMode)?
- };
+ .ok_or(EnvironmentError::DepthFormat)?;
+
+ let present_mode = [
+ PresentMode::MAILBOX,
+ PresentMode::FIFO,
+ PresentMode::RELAXED,
+ PresentMode::IMMEDIATE,
+ ]
+ .iter()
+ .cloned()
+ .find(|pm| caps.present_modes.contains(*pm))
+ .ok_or(EnvironmentError::PresentMode)?;
+
+ let composite_alpha_mode = [
+ CompositeAlphaMode::OPAQUE,
+ CompositeAlphaMode::INHERIT,
+ CompositeAlphaMode::PREMULTIPLIED,
+ CompositeAlphaMode::POSTMULTIPLIED,
+ ]
+ .iter()
+ .cloned()
+ .find(|ca| caps.composite_alpha_modes.contains(*ca))
+ .ok_or(EnvironmentError::CompositeAlphaMode)?;
let extent = caps.extents.end().to_extent(); // Size
let viewport = Viewport {
@@ -153,7 +143,7 @@ impl TargetChain {
ui_pipeline: &UiPipeline,
cmd_pool: &mut CommandPoolT,
properties: SwapchainProperties,
- ) -> Result<TargetChain, TargetChainCreationError> {
+ ) -> Result<TargetChain> {
let caps = surface.capabilities(&adapter.physical_device);
// Number of frames to pre-render
@@ -196,14 +186,15 @@ impl TargetChain {
properties.extent.width as usize,
properties.extent.height as usize,
)
- .map_err(|_| TargetChainCreationError::Todo)
- }?;
+ .context("Error creating depth buffer")?
+ };
let fat = swap_config.framebuffer_attachment();
let mut targets: Vec<TargetResources> =
Vec::with_capacity(swap_config.image_count as usize);
let mut sync_objects: Vec<SyncObjects> =
Vec::with_capacity(swap_config.image_count as usize);
+
for _ in 0..swap_config.image_count {
targets.push(
TargetResources::new(
@@ -219,18 +210,17 @@ impl TargetChain {
},
&properties,
)
- .map_err(|_| TargetChainCreationError::Todo)?,
+ .context("Error creating target resources")?,
);
- sync_objects
- .push(SyncObjects::new(device).map_err(|_| TargetChainCreationError::Todo)?);
+ sync_objects.push(SyncObjects::new(device).context("Error creating sync objects")?);
}
// Configure Swapchain
unsafe {
surface
.configure_swapchain(device, swap_config)
- .map_err(|_| TargetChainCreationError::Todo)?;
+ .context("Error configuring swapchain")?;
}
Ok(TargetChain {
@@ -286,36 +276,31 @@ impl TargetChain {
draw_buffers: &mut DrawBuffers<UvPoint>,
pipeline: &CompletePipeline,
vp: &Mat4,
- ) -> Result<
- (
- &'a mut crate::types::CommandBufferT,
- <SurfaceT as PresentationSurface<back::Backend>>::SwapchainImage,
- ),
- &'static str,
- > {
+ ) -> Result<(
+ &'a mut crate::types::CommandBufferT,
+ <SurfaceT as PresentationSurface<back::Backend>>::SwapchainImage,
+ )> {
self.last_syncs = (self.last_syncs + 1) % self.sync_objects.len();
-
- let syncs = &mut self.sync_objects[self.last_syncs];
-
self.last_image = (self.last_image + 1) % self.targets.len() as u32;
+ let syncs = &mut self.sync_objects[self.last_syncs];
let target = &mut self.targets[self.last_image as usize];
// Get the image
let (img, _) = unsafe {
self.surface
.acquire_image(core::u64::MAX)
- .map_err(|_| "FrameError::AcquireError")?
+ .context("Error getting image from swapchain")?
};
// Make sure whatever was last using this has finished
unsafe {
device
.wait_for_fence(&syncs.present_complete, core::u64::MAX)
- .map_err(|_| "FrameError::SyncObjectError")?;
+ .context("Error waiting for present_complete")?;
device
.reset_fence(&mut syncs.present_complete)
- .map_err(|_| "FrameError::SyncObjectError")?;
+ .context("Error resetting present_complete fence")?;
};
// Record commands
@@ -403,7 +388,7 @@ impl TargetChain {
draw_buffers: &mut DrawBuffers<UiPoint>,
img: &<SurfaceT as PresentationSurface<back::Backend>>::SwapchainImage,
pipeline: &UiPipeline,
- ) -> Result<&'a mut CommandBufferT, &'static str> {
+ ) -> Result<&'a mut CommandBufferT> {
let target = &mut self.targets[self.last_image as usize];
unsafe {
@@ -476,7 +461,7 @@ impl TargetChain {
&mut self,
img: <SurfaceT as PresentationSurface<back::Backend>>::SwapchainImage,
command_queue: &mut QueueT,
- ) -> Result<(), &'static str> {
+ ) -> Result<()> {
let syncs = &mut self.sync_objects[self.last_syncs];
let target = &mut self.targets[self.last_image as usize];
@@ -495,7 +480,7 @@ impl TargetChain {
);
command_queue
.present(&mut self.surface, img, Some(&mut *syncs.render_complete))
- .map_err(|_| "FrameError::PresentError")?;
+ .context("Error presenting to surface")?;
};
Ok(())
@@ -523,7 +508,7 @@ impl TargetResources {
fat: FramebufferAttachment,
dat: FramebufferAttachment,
properties: &SwapchainProperties,
- ) -> Result<TargetResources, TargetResourcesCreationError> {
+ ) -> Result<TargetResources> {
// Command Buffer
let cmd_buffer = unsafe { cmd_pool.allocate_one(hal::command::Level::Primary) };
@@ -535,14 +520,14 @@ impl TargetResources {
IntoIter::new([fat.clone(), dat]),
properties.extent,
)
- .map_err(|_| TargetResourcesCreationError::FrameBufferNoMemory)?
+ .context("Error creating colour framebuffer")?
};
// 2D framebuffer just needs the imageview, not the depth pass
let framebuffer_2d = unsafe {
device
.create_framebuffer(&renderpass_2d, once(fat), properties.extent)
- .map_err(|_| TargetResourcesCreationError::FrameBufferNoMemory)?
+ .context("Error creating depth framebuffer")?
};
Ok(TargetResources {
@@ -572,14 +557,14 @@ pub struct SyncObjects {
}
impl SyncObjects {
- pub fn new(device: &mut DeviceT) -> Result<Self, TargetResourcesCreationError> {
+ pub fn new(device: &mut DeviceT) -> Result<Self> {
// Sync objects
let render_complete = device
.create_semaphore()
- .map_err(|_| TargetResourcesCreationError::SyncObjectsNoMemory)?;
+ .context("Error creating render_complete semaphore")?;
let present_complete = device
.create_fence(true)
- .map_err(|_| TargetResourcesCreationError::SyncObjectsNoMemory)?;
+ .context("Error creating present_complete fence")?;
Ok(SyncObjects {
render_complete: ManuallyDrop::new(render_complete),
@@ -596,15 +581,3 @@ impl SyncObjects {
}
}
}
-
-#[derive(Debug)]
-pub enum TargetChainCreationError {
- Todo,
-}
-
-#[derive(Debug)]
-pub enum TargetResourcesCreationError {
- ImageViewError,
- FrameBufferNoMemory,
- SyncObjectsNoMemory,
-}